自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 数据库框架Mybatis(超详细版)

本文介绍了MyBatis框架的配置与使用。首先讲解了数据库准备,包括MySQL安装、Navicat连接和表创建。随后详细说明了Java对象与数据库的映射方法,包括注解方式实现CRUD操作、参数传递和结果映射的三种方式(SQL重命名、@Results注解、自动驼峰转换)。接着介绍了XML方式的实现,包括增删改查操作和resultMap配置。文中还对比了#{}和${}的区别,强调了SQL注入问题。最后讲解了数据库连接池的作用及Hikari和Druid两种实现。通过完整的代码示例展示了MyBatis的基本用法,帮

2025-05-27 10:45:00 855

原创 Spring中的控制反转和依赖注入(IoC和DI)以及常见面试题

Spring在不同情景下呢有不同的意思。(1)比如说你的项目里面使用到了Spring,那这里的Spring指的是Spring家族包含了各种各样的框架;(2)要是说Spring有什么特点其中一个是IoC那么这里指的就是Spring Core,Spring Framework。(Spring Core 是 Spring Framework 的核心模块,主要负责实现 IoC 和 DI 功能;

2025-05-05 10:45:00 890

原创 Python中的内置函数

其实从字面意思就能够了解,就是语言本身自带的函数。大佬们因为在日常编码中经常使用这些函数,就把这些函数写好了,像我们这种小白只需要拿过来用就行了。查看所有的内置函数(这里的结果太多,只截取了一部分)。#大写字母开头一般是内置常量名,小写这样说有点抽象,用代码来解释一下吧!return a+b#需要先导包#reduce(function,sequence) function--函数:必须是有两个参数的函数,sequence是序列:可迭代对象# 连续的两个元素作为参数,返回一个值,最后返回一个值。

2025-04-30 10:45:00 270

原创 Python中的匿名函数

lambda只能实现简单的逻辑,当遇到逻辑复杂且代码量较大时,不建议使用lambda表达式,否则会给后面的代码维护增加困难。lambda不需要写return来返回值,表达式 本身就是返回结果。函数名 = lambda 形参 : 返回值(表达式)函数名 = lambda 形参:表达式(返回值)默认参数必须写在非默认参数后面。调用:结果 = 函数名(实参)

2025-04-25 10:45:00 152

原创 Python中的函数和函数嵌套

格式:def func(*args) 这里的args是可以被其他名称替换的,但是我们默认使用args,你可以使用其他名称。函数名被调用几次,里面的代码就会执行几次,代码的执行顺序是从上往下执行,所以定义必须在调用函数之前。def 函数名(形参a,形参b): #形参:定义函数时,括号里面的变量。将具有独立功能的代码块组织成一个整体,使其具有特殊功能的代码集,称之为函数。含义:传入的值的数量是可以改变的,可以传入多个,也可以不传。作用:使用函数可以加强代码的复用性,提高程序编写的效率。

2025-04-23 10:45:00 342

原创 深浅拷贝的区别(面试常问)

拷贝最外层的对象,内部元素只拷贝了一个引用。在浅拷贝时,会创建一个新的对象,只拷贝第一层的数据,嵌套层会指向原来的内存地址。#赋值:等于完全共享资源,当其中一个值发生改变时会完全被另一个值共享。# 深拷贝数据变化只影响自己本身,跟原来的对象没有关联。注意:外层的内存地址不同,但是内层的内存地址相同)#内存地址不一样,说明不是同一个对象。优点:拷贝速度快,占用空间少,拷贝效率高。外层的对象何内部的元素都拷贝一遍。

2025-04-22 10:45:00 141

原创 Python中的集合(Java中的Set)

每次运行的结果不同,代表hash值在变化,所以其在hash表中的位置也就不同进而实现了集合的无序性,但是python中int整型的hash值就是它本身,所以它的hash值和顺序都不会变化。此外也正是因为有无序性,所以不能修改集合的值。discard:选择要删除的元素,有就会删除,没有则不会发生任何改变,即不会进行任何操作。注意:集合是无序的,并且里面的元素是唯一的,所以集合一般用于元组或者列表的去重。集合名 = {元素1,元素2,元素3.....}2.集合无序性的实现方式涉及hash表(了解)

2025-04-19 10:45:00 309

原创 Python中的字典(Java中的Map)

注意:字典以键值对的形式保存,键具有唯一性,但是值可以重复,重复会覆盖之前的值。键值对形式保存,键和值用:隔开,每个键值之间用,隔开。字典名 = {键1:值1,键2:值2,....}使用键值对,存储描述一个物体的相关信息。注意:存在就修改,不存在就新增。变量名.get(键名)变量名[键名] = 值。变量名[键名] = 值。

2025-04-18 09:53:40 170

原创 Python中的元组

当元组中只包含一个元素的时候,在末尾需要加上逗号,否则返回的是元组中唯一元素的数据类型。所有的元素都包含在小括号内,同时之间用逗号隔开,彼此之间可以是不同的数据类型。(1)元组内只有一个元素时末尾必须加逗号,列表则不需要。元组名 = (元素1,元素2,元素3.....)(2)格式化输出后面的()本质上就是一个数组。(2)元组只支持查询操作,不支持增删改操作。(3)数据不可被修改,保护数据的安全。(1)作为函数的参数和返回值。3.有关元组相关的操作。2.元组和列表的区别。

2025-04-17 10:45:00 1307

原创 Python中的列表(Java中的数组)

列表是一种处理一组有序项目的数据结构,用来储存数据的。

2025-04-16 10:45:00 817

原创 Python中的切片

步长:决定截取的间隔和截取的方向,步长的绝对值大小代表截取的间隔,正数表示从左到右截取,负数表示从右到左截取。比如2,那就是跳两格(中间隔开一个字符),从左到右开始截取。开始位置为-1,也就是在g的位置,步长没写默认为1,步长为正数时从左到右截取。结果:结束位置为-1,开始位置默认0,步长默认1,从左到右截取。(2)负数,从右到左数:-1,-2,-3,-4......(1)正数,从左到右数:0,1,2,3,4......结果:正常截取,注意包前不包后的原则。结果:开始位置不写,默认为0。

2025-04-10 10:45:00 253

原创 Python中的格式化输出

在学习格式化输出之前,我们需要先了解占位符。在将字符串格式化的时候,先要有一个模板,在这个模板之中有几个空位,这些空位需要用符号表示来填进去,这种符号就叫做占位符。通常占位符只是占据位置,占位符不是真实的输出的内容。

2025-04-06 10:45:00 370

原创 Spring中的日志

日志是一种工具,用来记录程序在运行时发生了什么事情。所以如上图所示,日志一般包含打印日志的时间,日志的级别,启动程序的进程id,哪一个线程打印的,哪一个类打印的日志,日志的内容。

2025-03-26 10:30:00 335

原创 TCP和UDP之间的区别

这里的连接其实是一个抽象的概念,其实本质上就是建立连接的双发都保存了彼此的信息。当然建立连接时双发都同意的,一旦一方不同意就建立不了连接,类似于结婚的时候领证一样。而UDP想要通信,就直接向对方发送,不需要对方同意,UDP自身也不保存对方的信息。

2025-03-10 11:00:00 132

原创 TCP/IP五层网络模型(OSI七层网络模型的简化版本)

描述的是网络通信的硬件设备比如我们使用的网线,光纤是什么规格的。

2025-03-10 10:30:00 151

原创 synchronized的原理(背后做了哪些事)

锁的颗粒度细的时候不一定都比颗粒度粗的时候要好,如果颗粒度细的锁涉及到反复加锁的操作,是不如锁颗粒度粗的,因为会涉及到反复的锁竞争。它是一种编译器优化的手段,在编译的时候如果发现加锁的代码不需要加锁,编译器就会将锁给优化掉。比如说StringBuffer和StringBuilder中因为StringBuffer加了锁所以它是线程安全的,当在编译的时候,如果发现你在单线程的情况下使用,不需要加锁,此时就会将锁消除掉。一般锁升级的步骤是 无锁->偏向锁->自旋锁(轻量级锁)->重量级锁。

2025-02-28 13:02:43 242

原创 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 215

原创 常见的锁策略

如果预测接下来锁冲突的概率不大,就可以少做一点工作,就称为乐观锁如果预测借来下锁冲突的概率很大,就应该多做一点工作,就成为悲观锁。

2025-02-28 11:00:00 230

原创 实现一个定时器

【代码】实现一个定时器。

2025-02-26 13:45:00 134

原创 阻塞队列实现生产者消费者模型

生产者将生产的内容放到阻塞队列中,而消费者就从阻塞队列中获取到内容,这就是生产者消费者模型。其实就类似于包饺子一样,包饺子涉及到和面,擀面皮,和包饺子等一系列操作。那其中我们可以把擀面皮看作成生产者,而包饺子可以看作消费者,那阻塞队列就相当于放饺子皮的地方。

2025-02-25 11:12:26 368

原创 如何实现单例模式

创建对象的时候粗略可以分为三步,1.在内存中申请空间2.在内存中构造对象3.将该对象的地址返回给instance引用对象.所以就会出现当两个线程同事访问的时候,其中一个线程正在创建对象,但是只执行了1和3,2还没执行到呢,但是这个时候另一个线程执行了第一个if判断instance不为空,但是不合法,直接return了,这个时候就会出现问题。我们这里的思路是我第一次创建对象的时候需要加锁,那我们第二次调用的时候如果对象已经被创建出来了,那我们就不需要进行加锁了,已经有了对象,直接返回就可以了。

2025-02-24 10:49:56 400

原创 创建线程的几种方法

注意这里用的是thread.start();不是thread.run();的原因是thread.start();是先去创建一个线程再来调用run方法,所以直接使用run方法是不会创建出一个线程的。

2025-02-21 11:19:53 297

原创 冒泡排序以及优化

首先我们看上图所示,这是整个冒泡排序的过程。我们先来看进行遍历一次冒泡排序如何去做。(1)将初始位置的数与下一个数进行比较大小,如果当前位置的数 > 下一个位置的数,则交换位置,然后++(也就是进行下一个数的比较),如果当前位置的数 < 下一个位置的数,则直接进行下一个数的操作。一直将最大的数放置最后一位为止,那么一次冒泡排序便完成了。所以到这一步我们可以构思出需要一个for循环来进行遍历,还有一个if语句来进行判断大小并且判断完成之后选择是否交换两个数的位置。

2025-02-19 13:23:30 342

原创 自动化测试

利用Thread类中的方法来进行等待,主要用于调试,在真实的自动化测试中不常用到。优点:代码简单,容易编写和理解,直接阻塞程序。缺点:大大增加了自动化测试的时间。

2025-02-18 11:52:07 752

原创 mysql中的事务

虽然引进了事务,但是事务到底是什么?它的本质其实就是把原来多个sql语句打包成一个整体,多个sql语句构成的一系列操作要么都执行成功,要么都执行失败.就比如说上述的转账操作.account->表名,balance->要修改数据的名称.本来是两条sql语句,可能会有一条语句执行成功,一条不成功.但是加上事务之后两条sql语句成为一个整体,只会出现执行成功和执行失败两种可能.

2023-10-17 17:35:33 70

原创 mysql中索引利用的数据结构- (B树和B+树)

而索引之所以能够来帮助我们提升查询的速度,主要依赖于它的数据结构->B+树,那在提到B+树之前就得说一下我们的B树了.B树的本质上就是一个N叉搜索树与二叉树搜索树不同的是一个节点上可以保存很多的值(数据),根据这些值可以分叉出很多子节点,子节点的值都比节点的值要小,这个时候查询的速度就比其他数据结构快很多.(这里说明一下为什么不用哈希表,虽然说哈希表查询的速度很快但是它不能进行范围的查询,就比如说我想要查询100-200之间的数据,这个时候哈希表就做不到这样的查询了。

2023-10-17 12:03:44 60

原创 java中的线程池

在java中因为进程的创建和调度太重(太耗费时间和资源),所以我们引入了线程.但是所谓没有对比就没有伤害,在后来的开发要求更加高效时,线程已经不能满足程序员们的需求了,这个时候就有了两条路可供选择.(1)创建出更轻量的线程->协程(2)提前准备好多个线程,需要的时候就直接拿来用->线程池因为java的标椎库中还没有引进协程所以我们一般使用线程池来解决问题.

2023-10-11 16:30:08 60

原创 Java中的死锁

当一个线程对于一个对象上锁时候,对于这个锁再次上锁,如果此时不能够产生死锁则称之为可重入,如果产生了死锁则称为不可重入的,在Java中synchronize是可重入的.具体的实现是:第一次加锁对象时会记录下此时这个锁是属于哪一个线程的,当再次加锁时会去检查一下这个锁是否属于同一个线程如果是则开放绿灯,否则阻塞等待.

2023-10-02 01:31:55 48 1

原创 初步认识操作系统,进程和内存管理

进程实际上就是跑起来的程序,当你在电脑上打开一个软件,它在后台运行起来了,此时它就是进程.它是操作系统分配资源的基本单位.

2023-09-27 21:39:01 86 1

原创 关于计算机小白内心的未来

虽然用的人不会知道创造他的人是谁,但是别人使用的时候我可以自己告诉自己看别人用的都是你写的应用,为此我愿意从0开始,毕竟网上的心灵鸡汤都说了种一棵树最好的时候是十年前,其次是现在。现在回想起来之前的三年都不清楚自己干了些什么。可能留在记忆里的只有大一时候疯狂打着王者,大二的时候玩着LOL,大三的时候玩着原神,就这样快玩到了大四,到了现在感觉什么都没意思。而我心目中的公司不是所谓的大厂,因为我知道我不是对自己太狠的人,没必要去一个自己即有可能进不去,也不是即有可能了是很大可能进不去又不适合自己的公司。

2023-08-08 10:19:06 50

空空如也

空空如也

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

TA关注的人

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