- 博客(19)
- 收藏
- 关注
原创 Python中的格式化输出
在学习格式化输出之前,我们需要先了解占位符。在将字符串格式化的时候,先要有一个模板,在这个模板之中有几个空位,这些空位需要用符号表示来填进去,这种符号就叫做占位符。通常占位符只是占据位置,占位符不是真实的输出的内容。
2025-04-06 10:45:00
291
原创 Spring中的日志
日志是一种工具,用来记录程序在运行时发生了什么事情。所以如上图所示,日志一般包含打印日志的时间,日志的级别,启动程序的进程id,哪一个线程打印的,哪一个类打印的日志,日志的内容。
2025-03-26 10:30:00
278
原创 TCP和UDP之间的区别
这里的连接其实是一个抽象的概念,其实本质上就是建立连接的双发都保存了彼此的信息。当然建立连接时双发都同意的,一旦一方不同意就建立不了连接,类似于结婚的时候领证一样。而UDP想要通信,就直接向对方发送,不需要对方同意,UDP自身也不保存对方的信息。
2025-03-10 11:00:00
119
原创 synchronized的原理(背后做了哪些事)
锁的颗粒度细的时候不一定都比颗粒度粗的时候要好,如果颗粒度细的锁涉及到反复加锁的操作,是不如锁颗粒度粗的,因为会涉及到反复的锁竞争。它是一种编译器优化的手段,在编译的时候如果发现加锁的代码不需要加锁,编译器就会将锁给优化掉。比如说StringBuffer和StringBuilder中因为StringBuffer加了锁所以它是线程安全的,当在编译的时候,如果发现你在单线程的情况下使用,不需要加锁,此时就会将锁消除掉。一般锁升级的步骤是 无锁->偏向锁->自旋锁(轻量级锁)->重量级锁。
2025-02-28 13:02:43
227
原创 CAS(比较与交换)
CAS(M,A,B)的含义就是比较M和A的值是不是相同,如果相同则将B的值赋值给M,并且返回true;比如int 对于++操作不是原子的,它需要(load,add,save),而AtomicInteger类是基于CAS对int进行了封装,它对于++操作是原子的。每次修改的时候让版本号自增,CAS每次去判断版本号有没有改变,没有改变就注定没有别的线程穿插。这显然是不合理的,但是上述情况发生的概率很低,所以CAS在通常情况下不会有什么bug,但是有可能在极端情况下出现ABA问题。3.CAS引发的ABA问题。
2025-02-28 12:33:01
187
原创 阻塞队列实现生产者消费者模型
生产者将生产的内容放到阻塞队列中,而消费者就从阻塞队列中获取到内容,这就是生产者消费者模型。其实就类似于包饺子一样,包饺子涉及到和面,擀面皮,和包饺子等一系列操作。那其中我们可以把擀面皮看作成生产者,而包饺子可以看作消费者,那阻塞队列就相当于放饺子皮的地方。
2025-02-25 11:12:26
321
原创 如何实现单例模式
创建对象的时候粗略可以分为三步,1.在内存中申请空间2.在内存中构造对象3.将该对象的地址返回给instance引用对象.所以就会出现当两个线程同事访问的时候,其中一个线程正在创建对象,但是只执行了1和3,2还没执行到呢,但是这个时候另一个线程执行了第一个if判断instance不为空,但是不合法,直接return了,这个时候就会出现问题。我们这里的思路是我第一次创建对象的时候需要加锁,那我们第二次调用的时候如果对象已经被创建出来了,那我们就不需要进行加锁了,已经有了对象,直接返回就可以了。
2025-02-24 10:49:56
352
原创 创建线程的几种方法
注意这里用的是thread.start();不是thread.run();的原因是thread.start();是先去创建一个线程再来调用run方法,所以直接使用run方法是不会创建出一个线程的。
2025-02-21 11:19:53
266
原创 冒泡排序以及优化
首先我们看上图所示,这是整个冒泡排序的过程。我们先来看进行遍历一次冒泡排序如何去做。(1)将初始位置的数与下一个数进行比较大小,如果当前位置的数 > 下一个位置的数,则交换位置,然后++(也就是进行下一个数的比较),如果当前位置的数 < 下一个位置的数,则直接进行下一个数的操作。一直将最大的数放置最后一位为止,那么一次冒泡排序便完成了。所以到这一步我们可以构思出需要一个for循环来进行遍历,还有一个if语句来进行判断大小并且判断完成之后选择是否交换两个数的位置。
2025-02-19 13:23:30
297
原创 自动化测试
利用Thread类中的方法来进行等待,主要用于调试,在真实的自动化测试中不常用到。优点:代码简单,容易编写和理解,直接阻塞程序。缺点:大大增加了自动化测试的时间。
2025-02-18 11:52:07
693
原创 mysql中的事务
虽然引进了事务,但是事务到底是什么?它的本质其实就是把原来多个sql语句打包成一个整体,多个sql语句构成的一系列操作要么都执行成功,要么都执行失败.就比如说上述的转账操作.account->表名,balance->要修改数据的名称.本来是两条sql语句,可能会有一条语句执行成功,一条不成功.但是加上事务之后两条sql语句成为一个整体,只会出现执行成功和执行失败两种可能.
2023-10-17 17:35:33
53
原创 mysql中索引利用的数据结构- (B树和B+树)
而索引之所以能够来帮助我们提升查询的速度,主要依赖于它的数据结构->B+树,那在提到B+树之前就得说一下我们的B树了.B树的本质上就是一个N叉搜索树与二叉树搜索树不同的是一个节点上可以保存很多的值(数据),根据这些值可以分叉出很多子节点,子节点的值都比节点的值要小,这个时候查询的速度就比其他数据结构快很多.(这里说明一下为什么不用哈希表,虽然说哈希表查询的速度很快但是它不能进行范围的查询,就比如说我想要查询100-200之间的数据,这个时候哈希表就做不到这样的查询了。
2023-10-17 12:03:44
43
原创 java中的线程池
在java中因为进程的创建和调度太重(太耗费时间和资源),所以我们引入了线程.但是所谓没有对比就没有伤害,在后来的开发要求更加高效时,线程已经不能满足程序员们的需求了,这个时候就有了两条路可供选择.(1)创建出更轻量的线程->协程(2)提前准备好多个线程,需要的时候就直接拿来用->线程池因为java的标椎库中还没有引进协程所以我们一般使用线程池来解决问题.
2023-10-11 16:30:08
41
原创 Java中的死锁
当一个线程对于一个对象上锁时候,对于这个锁再次上锁,如果此时不能够产生死锁则称之为可重入,如果产生了死锁则称为不可重入的,在Java中synchronize是可重入的.具体的实现是:第一次加锁对象时会记录下此时这个锁是属于哪一个线程的,当再次加锁时会去检查一下这个锁是否属于同一个线程如果是则开放绿灯,否则阻塞等待.
2023-10-02 01:31:55
35
1
原创 初步认识操作系统,进程和内存管理
进程实际上就是跑起来的程序,当你在电脑上打开一个软件,它在后台运行起来了,此时它就是进程.它是操作系统分配资源的基本单位.
2023-09-27 21:39:01
58
1
原创 关于计算机小白内心的未来
虽然用的人不会知道创造他的人是谁,但是别人使用的时候我可以自己告诉自己看别人用的都是你写的应用,为此我愿意从0开始,毕竟网上的心灵鸡汤都说了种一棵树最好的时候是十年前,其次是现在。现在回想起来之前的三年都不清楚自己干了些什么。可能留在记忆里的只有大一时候疯狂打着王者,大二的时候玩着LOL,大三的时候玩着原神,就这样快玩到了大四,到了现在感觉什么都没意思。而我心目中的公司不是所谓的大厂,因为我知道我不是对自己太狠的人,没必要去一个自己即有可能进不去,也不是即有可能了是很大可能进不去又不适合自己的公司。
2023-08-08 10:19:06
38
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人