自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(35)
  • 收藏
  • 关注

原创 多线程案例之线程池

线程池是什么?线程池就是创建若干个可执行的线程放入一个池(容器)中,有任务需要处理时,会提交到线程池中的任务队列,处理完之后线程并不会被销毁,而是仍然在线程池中等待下一个任务。 线程池中线程的数量通常完全取决于可用内存数量和应用程序的需求。标准库中的线程池,我们直接看代码演示:我们要自己实现一个线程池需要以下几个步骤:1、先描述任务(直接使用Runnable)2、需要组织任务(直接使用BlockingQueue)3、能够描述工作线程4、需要组织这些线程5、需要实现往线程池里添加任务

2022-04-21 22:02:00 375

原创 多线程案例之定时器

定时器是什么?类似于一个 “闹钟”. 达到一个设定的时间之后, 就执行某个指定好的代码.我们先来看看标准库中的定时器:标准库中提供了一个 Timer 类. Timer 类的核心方法为 schedule .schedule 包含两个参数. 第一个参数指定即将要执行的任务代码, 第二个参数指定多长时间之后执行 (单位为毫秒).这里我们注意一下这个schedule方法,这里面其实就是实现了一个Runnable接口,这为我们后面自己设置定时器提供了思路。运行结果:接下来我们实现自己的一个定时器:

2022-04-21 21:33:51 296

原创 Java多线程安全之阻塞式队列

2022-04-21 20:37:22 978

原创 多线程案例之单例模式(饿汉模式、懒汉模式)

单例模式1、设计模式:什么是设计模式?设计模式就是针对一些问题场景,大佬们总结除了一些固定的套路,按照这个套路实现代码。就会少走很多弯路。2、常见的设计模式有两种:单例模式、工厂模式单例模式中的代码的某个类只能有一个实例,不能有多个。3、单例模式分为“饿汉”和“懒汉”两种。4、饿汉模式:这里的实例在类加载阶段就会直接创建实例。5、懒汉模式-单线程版我们一步步来看懒汉模式,首先与饿汉模式的区别是:在类加载的时候不创建实例,而是在用的时候在创建实例。我们在这里并没有直接创建实例,而是在

2022-04-21 17:37:29 648

原创 wait和notify方法

1、wait:让当前线程进入等待状态、notify让当前线程退出等待状态,调用wait方法的线程就会陷入阻塞,阻塞到有其他线程通过notify来通知。2、wait和notify都是OBJECT对象的方法 ,使用这两个方法就得先创建Object静态方法:3、使用这两个方法必须搭配synchronized,不然就会出现异常。4、如果有多个线程进入等待状态,notify方法不能指定那个线程释放,这个过程是随机的,这样我们可以通过上述的静态方法来设置多组wait和notify.5、7.4 wait 和 s

2022-04-19 22:10:58 648

原创 java线程的几种状态和线程安全的原因和几种解决办法

线程的几种状态:1.NEW:Thread对象创建好了线程,但是还没有调用start();2.RUNNABLE:就绪状态,可工作的,又可以细分为正在工作中和即将开始工作。3:BLOCKED:当前线程在等待锁,导致了阻塞。4:WAITING:当前线程在等待唤醒 导致了阻塞。5:TIMED_WAITING:当前的线程在一定时间内是阻塞的。6:TERMINATED: 操作系统中的线程已经执行完毕 销毁了 但是Thread对象还在 。线程安全的原因和几种解决办法:操作系统调度线程的时候是随机的,正是因

2022-04-18 20:56:18 374

原创 多线程的创建、启动、中断、等待、休眠、获取线程实例

1、创建线程1.1 继承Thread 重写run方法1.2:实现 Runnable接口, 重写 run1.3:继承 Thread, 重写 run, 使用匿名内部类 这是第一种方法的延申1.4:实现 Runnable, 重写 run, 使用匿名内部类 这是第二种方法的延申1.5:使用 lambda 表达式 其实就是第四种的延申。通常认为Runnable这种写法更好一点 能够让线程和线程执行的任务 更好的解耦.2、线程的启动run 单纯的只是一个普通的方法 描述了任务的内容 并没有创建

2022-04-17 21:54:35 506

原创 进程和线程的联系和区别

进程和线程:1:进程可以看作是一个程序一次运行的过程,在操作系统内部也是分配资源的基本单位。2:每一个PCB对象就是一个实实在在运行的程序,也就是进程,PCB有以下几种属性:2.1:pid进程的身份标识2.2:内存指针 指明了进程要执行的代码指令和依赖的数据在内存的哪里。2.3:文件描述符:为了程序运行的时候方便与文件打交道。2.4:3:并行:两个CPU核心 同时执行两个任务的代码并发:微观上一个CPU 执行一会任务1 在执行一会任务2 在执行一会任务3 然后循环,只要切换的足够快,宏观上看

2022-04-16 21:30:03 162

原创 数据库的事务和JDBC编程

事务1、事务是什么? 举个例子:比如A向B转钱,A减少3万,B增加3万,这两个操作是就属于一组操作,要么全部成功,要么全部失败。2、事务的几个性质:1:原子性 把一组操作按照一个操作来执行,如果中间环节出错了,就按照逆操作,再回到原点。2:一致性 执行事务前后,数据始终处于一个合法的状态。 3:持久性:事务一旦执行完毕,此时对于数据的修改就是持久生效的,写入磁盘的。(不持久生效是写入内存的)4:隔离性3、开启事务:start transaction;执行SQL语句回滚或者提交 回滚就是全部失败

2022-04-14 15:21:33 142

原创 数据库的索引

数据库的索引:1、索引是什么:索引就类似于书的目录,是数据表所有记录的引用指针。2、索引要解决的问题:避免过多的顺序查找,因为顺序查找要逐步进行查询,这样时间会很慢,有了索引就可以快速定位到需要的数据。这样可以加快查找的效率。3、索引的应用场景:索引主要应用于查询较多,删除、更新、插入不频繁的工作中,因为删除、更新、插入需要同步设置调整索引,也会额外占用时间。4、索引的数据结构:B+树5、索引为什么不用哈希表:因为哈希表一般是判定相等或者不相等,无法解决大于、小于的情况。6、为什么不用二叉树:比

2022-04-14 11:53:45 930

原创 哈希表的有关问题

1:概念:通过某种函数使元素的存储位置与它的关键码能够建立一一映射的关系,提高了搜索效率,时间复杂度为o(1).2:哈希函数:key%数组的长度3:foreach的循环对象一般是一个集合,List、ArrayList、LinkedList、Vector、数组等(遍历时常用)4:在存放数据的时候难免会发生冲突,比如4和44,他俩经过散列函数的计算都是4,这样就产生了冲突。避免冲突的方法就是负载因子调节,负载因子是填入表中的元素/散列表的长度 ,java限制了负载因子为0.75.5:如果发生冲突的无法被

2022-04-01 20:31:11 475

原创 二叉搜索树

1:概念:二叉搜索树的左子树如果不为空就一定小于根节点的值,如果右树不为空也一定大于根节点的值。而且二叉搜索树的左右子树也都是二叉搜索树。2:二叉搜索树的插入,一定要找到叶子结点才能插入,每一层都根据概念来判断进入左树还是右树数据的插入必须要有一个parent来记录父节点,然后插入的时候必须找到叶子结点进行插public boolean insert(int key){Node node=new Node(key);if(rootnull){root=node;return true ;}

2022-03-29 22:19:35 131

原创 Map和Set集合

MAP的相关知识:1:map和set是一种专门进行搜索的容器,一般适用于动态查找的集合容器。2:map存储的是K-V结构,K是唯一的,value是可以重复的。3:map最重要的一个方法就是//Set<Map.Entry<K, V>> entrySet() 返回所有的 key-value 映射关系, map.entrySet类型就是把value和key打包在一起,Set<Map.Entry<String,String>>的作用就在于把 打包在一起的类型转换

2022-03-24 21:26:28 129

原创 常见几种排序的思想

注意:下面排序都默认从小到大1、直接插入排序 思想:让i从第二个数字开始往后走,j是i左边的第一个数字,然后把i的数字给tmp,比较j与tmp的大小,如果j大于tmp,就把j往后挪一个位置,然后j继续往左边走,知道j小于0,证明左边已经没有数字了,然后i继续往后走,在用上面的方法进行判断。最后要将tmp的值在赋给j+1的位置。代码:for (int i = 1; i <array.length ; i++) {int j=i-1;int tmp=array[i];for (;j>=0

2022-03-22 21:26:46 764

原创 优先级队列(堆)PriorityQueue

1:左子树结点=父节点2+1 右子树结点=父节点2+2已经知道孩子结点是i。则父节点是(i-1)/2.2:堆其实就是一颗完全二叉树,保存在数组中,主要是为了找到数组中的最值。分为大堆和小堆3:向下调整:以大堆为例:找到最后一课子树的根节点,然后比较根节点和子节点的值,谁大放到根节点,然后父节点在指向被换的子节点,继续判断。小堆的话 从最上面开始比较,比较根和左右的大小,谁小就放在根,然后根指向被换的子节点。4:堆的应用:入堆:向上调整。以大堆为例,谁大就放在根节点,然后让孩子等于父亲,父亲继续往上

2022-03-20 14:18:16 192

原创 二叉树的有关基础知识

二叉树有关知识:1:前序,中序,后序遍历,在写代码的时候注意递归和打印的顺序问题就行。2:满二叉树:每一层的结点都达到了最大值,2的k次方-1个。完全二叉树:所有的编号都是顺序排下去的,不能有空的顺序。3:递归的思想:把一个树分成左子树和右子树,然后得出来的值给上一层,求结点个数和叶子结点的个数,都分成左右两个子树,然后相加。注意:返回的时候一定要加上本身,所以要加1.就和求高度也是一样的,在返回的时候一定要加上自身。但是在求叶子节点不可以不用,因为叶子节点有另外的限制条件,左右子树都为空。4:

2022-03-18 17:45:32 433

原创 java数组的学习

心得体会;1:java里的数组在栈上,但是初始化的值在堆上,就好比调用。array数组名指向的是堆上{1,2,3,4}的首地址.2:数组的遍历有for in for each,前者可以修改数组的值,后者一般只用于打印。3.内置类型的传递和数组传递的不同。内置类型改变形参的值,实参不改变,而在数组中交换两个变量的值就可以实现。改变数组中的值,会改变。其实数组也是保存的地址,传递参数就好比指向同一块地址。4.返回指定数组的内容的字符串表示形式String ret=Arrays.toString(ar

2022-01-09 21:55:52 243

原创 java方法的使用和递归

1:public static //方法中必须要有的,当前所有的方法写完之后会在main方法中调用,因为mian方法是静态的,方法对应C中的函数2:void 返回值 可以是int 其他的,可有可无 具体看需求3:main 方法的名字,小驼峰的形式 maxNum4: (String[] args)是形式参数列表5:return 代表函数的结束,下面的代码将不会被执行6: java当中只有按值传递,没有按地址传递。7:方法的重载:1:函数名字相同 2:返回值不做要求,可以相同,可以不同3:参数的个

2022-01-06 22:37:03 295

原创 JAVA--数据类型

心得体会:1:JAVA中的数据类型分为两大类:第一大类是基本数据类型:字节数 1 2 2 4 8 4 8 没有规定数据类型 byte char short int long float double boolean包装类 Byte Character Short Integer Long Float Double Boolean引用数据类型:类,String 数组 抽象类 接口 枚举2:用包装类的时候一定要记得首字母大写。3;+ 这个符号只有有拼接,就全部

2021-12-30 21:35:39 157

原创 三子棋心得体会

三子棋代码的心得体会:1:步骤;先打印菜单输入==选择判断初始化棋盘打印棋盘下棋的逻辑:玩家下棋电脑下棋判断输赢:玩家赢电脑赢平局2:打印菜单用do,while循环,因为不需要判断直接打印菜单。3:输入一个数字,来做判断,使用switch语句来判断,在判断进入游戏之后,调用一个游戏函数。4:开始玩游戏的时候先初始化数组里的值哦,使其全部成为空格,然后打印出来,利用循环和条件语句打印整个棋盘,打印分隔符的时候注意循环和条件语句的条件。5:打印好整个棋盘后,开始玩游戏,玩家开始

2021-12-27 23:24:45 1936

原创 数组的有关心得体会

学习心得:1:补充条件语句:if 和 else if一次判断只能进去一个2://strlen 是一个库函数,计算的是字符串的长度,并且只能针对字符串,/计算\0之前的字符个数。3://sizeof是一个操作符//sizeof是用来计算变量所占内存空间大小的,任何类型都是可以用是的,只关注空间大小,不在乎是否存在\0。4:VS不支持边长数组5:数组的不完全初始化,其余元素默认为0;6:给数组初始化值的时候,可以不设置长度,数组会根据设定的初始化值赋予长度。7://int arr[] = { 0

2021-12-26 22:21:38 764

原创 函数有关知识;定义,声明,递归等。

知识总结:1.在调用函数的时候,想改变原本的函数就使用传址,不改变的话就是用传值。2.//void不需要返回,但是我们在某种情况想反回,就直接在下面写个return;//函数的返回类型//void - 无返回//char int float////void test1()//{// int n = 5;// printf(“hehe\n”);// if (n == 5)// return;3.函数可以嵌套调用,但是不能嵌套定义。4.// printf("%d", printf(

2021-12-14 22:45:41 998

原创 函数有关学习心得

学习心得:1.一般函数调用分为两种:传值和传址,如果我们通过形参来改变实参的话,我们要传址,形参用指针来接收。如果不需要的话,可以直接传值。2.参数传递如果是数组的话,默认传的是数组的首地址,所以设计到计算数组的长度要在主函数中进行。int binary_search(int arr[], int k,int sz)//数组在传参的时候,实际上传的是数组首元素的地址,所以一旦在这里算数组长度的时候,算出来的长度只能为1.实际上 int arr[]==int *p;binary_search(arr,

2021-12-13 21:41:32 789

原创 循环,随机数等心得体会。

心得体会:1.switch中,只要没有break,case和default都得按顺序执行。2.字符在存储的时候,存的是ASCII码值。3.while()中,0表示假 非0表示真。4.static static修饰局部变量改变了变量的生命周期,让静态局部变量出了作用域依然存在,到程序结束,生命周期才结束。//static 一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。//一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源

2021-12-12 22:03:58 325

原创 空心三角形和带空格直角三角形

心得体会:1:算数转换的时候,一般向高的字节进行转换。2:*p++是先指向p存放地址的值,然后在指向p里存放的地址加一,只改变指向的地址。3:将 i like beijing.变成beijing.like i,可以先将三个单词分别逆序,然后再将整个数组进行逆序。4:重点:当输入有空格的时候,我们可以用gets()函数。// char arr[100] = { 0 };// //输入// gets(arr);5:一般打印空格 * 的时候,先观察有没有规律,比如当行和列符合哪类要求的时候,打印什

2021-12-08 21:02:59 810

原创 数据存储和补充指针有关知识;

心得体会:char //字符数据类型,1个字节short //短整型,2个字节int //整形,4个字节long //长整型 4个字节long long //更长的整形 八个字节float //单精度浮点数 四个字节double //双精度浮点数 八个字节int 当作有符号数看待,//int main()//{// char a = -1;// signed char b = -1;// unsig

2021-12-07 22:01:02 440

原创 分支循环以及相关的编程思想

if语句:1./if后面如果跟一条语句可以不用加2大括号,如果跟着多条语句,就要加大括号。2.//if (18 <= age < 40)//这个是错误程序,因为如果输入的是5,18<=5是假,为0,0<40为真,条件仍可以进入。3.else和离得最近的if匹配的,不用管对齐。4.if (5 == a)//最好给一个变量赋值的时候,把常量写在前面。当写错的时候,容易发现错误。5.for (i = 0; i<10; i++){if (i = 5)printf("%d

2021-11-27 21:33:20 223

原创 数据存储和编程题总结。

心得体会:1.int long short 这三种类型一般默认为有符号型,char大部分被默认为有符号型。若要区别有符号和无符号可以加入unsigned signed。负数被输入,不只是简单的去掉符号,要进行转换成补码来进行判断。2.在计算机中,只执行加法。16进制存储,两个数字为一个字节,不足的在前面补0。3.计算机中存储分为大小端,大端:高位存低地址,低位存高地址。小端:低位存低地址,高位存高地址。4.模拟实现strcpy函数代码;/实现strcpy//char my_strcpy(char

2021-11-24 21:36:51 217

原创 编程实用技巧总结

学习心得体会:1.//F5开始调试,通常使用F5跳到想要的断点处和F9设置断点,配合使用。//F10逐过程,可以跳过有些函数。F11逐语句。2.在主函数定义的变量,在循环中使用完后数值依然存在,所以要求阶乘的话,要在循环内重置变量。//int main()//{// int n = 0;// scanf("%d", &n);//3// //计算n的阶乘// int i = 0;// int ret = 1;// int j = 0;// int sum = 0;// //1

2021-11-22 11:30:18 619

原创 结构体和其他题中知识点

1.让一个数的二进制位与1,可以判定该二进制的最后一位是否为1.,可以让一个二进制每次除以2(就好比二进制位右移一位)然后与1来判定二进制最后一位是1还是0.2.拓展:2的k次方里只有一个1,如果要判断一个数是不是2的K次方,可以让该数字与该数字减一按位与,如果直接等于0,则该数字是2的K次方。3.if (i > sizeof(i))//-1 > 4,sizeof是无符号整型的!i因为是-1,所以要转换成无符号整型。4.while (scanf("%d", &n) != EOF)/

2021-11-20 21:45:16 455

原创 指针知识点

指针知识总结:1.int* pa = &a;//a是变量,&a是地址,pa是指针变量,一般我们称为指针,int为定义指针变量,大小一般是4个字节。2.二进制存储的时候,小端在小地址,32位地址线,一个地址管理一个字节,2的32次方的地址,2的32次方字节,除1024得kb,再除以1024得mb,在除以1024得GB,结果为4GB。3.指针的类型决定了一次能访问几个字节,还有每次向前或者向后走一步,走多大距离。int a = 0x11223344;//存放16进制的数字,11为一个字节,

2021-11-20 21:27:48 859

原创 2021-11-15

#define _CRT_SECURE_NO_WARNINGS 1学习心得:// char arr[] = { ‘b’, ‘i’, ‘t’ };没有结束符号\0,所以是随机值,比如”abc"后面默认有一个\0//// printf("%d\n", strlen(arr));//每一次打印出来是个随机的值,因为没有字符的结束\0,但是如果是"abc"就会是3.////如果想使用来自其他文件(外部文件)的 全局变量,先要声明一下////extern是一个关键字,是专门用来声明外部符号的

2021-11-15 22:14:35 664

原创 2021-11-14

学习心得:前置++实时改变变量的值,后置++先使用在改变变量的值,注意:printf也算使用变量强制类型转换:如果转成整数,则只取整数部分逻辑反操作,只看逻辑 不看数值因为只要是看指针大小和类型无关。一般都是4个字节// printf("%d\n", sizeof(arr));//(1)10个整型 40,sizeof后面放数组名,好比传了整个数组// test1(arr);//这块传参只传了首字符的地址// test2(ch);//这块只传了首字符的地址逗号表达式从左向右依次执行。整个表达式的

2021-11-14 21:53:57 719

原创 2021-11-13

#define _CRT_SECURE_NO_WARNINGS心得: 计算机里存的是数字的二进制补码,任何对二进制的操作都是对补码的操作,但是显示却要使用原码来判断。正数的原码 反码 补码都一样负数的原码:最高位变成1,反码每一位求反,最高位不变,补码反码加一左移:右边补零右移:常用 左边补符号位区别:sizeof(arr[10])代表整个数组的长度。为40字节。而strlen代表的是字符长度,要考虑到“abc”这种情况,strlen(“abc”)=3,实际还有个\0,sizeof()=4.当

2021-11-13 12:14:12 453

原创 2021-11-06

这里写自定义目录标题/ 笔记本 fn+F5/ 笔记本 fn+F5//hello world//#include <stdio.h>//int main()//{//printf(“hello world\n”);//return 0;//}// 首先要知道main 函数//main 函数是程序的入口//程序是从Main函数的第一行开始执行的//有且仅有一个//int 表是main函数结束后返回一个整型的值//0 就是一个整数,在main函数结束的时候被返回// pr

2021-11-06 15:34:05 88

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除