自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 线程安全以及解决方案

例如:定义了一个变量count,执行count++这种操作,本质上是三个CPU指令,load(将count的值读入cpu寄存器中)、add(将寄存器的数据进行+1)、save(将寄存器中的数据读入到内存中),而CPU执行指令都是以一个指令为单位顺序进行的,试想,有两个线程同时执行count++操作,这些一个一个的指令就会抢占执行,线程一的add的操作刚完,线程二的add就抢占了下一个位置…线程的调度是随机的,在有些调度下,代码的逻辑会出现问题,结果会与预计结果不同,但这个是内核实现的,没有办法改变。

2024-04-24 13:49:20 855

原创 进程和线程

虽然多进程也能实现 并发编程,但是由于进程太重量,效率不高,创建进程、销毁进程、进程调度时间的消耗较多,主要消耗在申请资源, 线程比进程更轻量,线程之间共享进程的内存空间和硬盘资源,创建线程,不需要重复去申请资源,省去了这一部分的开销 ,提高了系统的效率和资源利用率。PCB是操作系统进行进程调度和管理的基础,当操作系统需要切换进程时,会保存当前进程的上下文信息到其对应的PCB中,然后加载下一个将要执行的进程的PCB,并将其上下文信息恢复,从而实现进程的切换。方法1 继承 Thread 类。

2024-04-24 13:48:20 601

原创 数据结构-----枚举、泛型进阶(通配符?)

枚举是在JDK1.5以后引入的。但是常量举例有不好的地方,例如:可能碰巧有个数字1,但是他有可能误会为是RED,现在我们可以直接用枚举来进行组织,这样一来,就拥有了类型,枚举类型。而不是普通的整形1.优点:将常量组织起来统一进行管理使用场景:错误状态码,消息类型,颜色的划分,状态机等等…本质:是java.lang.Enum 的子类,也就是说,自己写的枚举类,就算没有显示的继承 Enum ,但是其默认继承了这个类。

2024-04-12 22:04:09 996

原创 数据结构-----Lambda表达式

Lambda表达式的优点很明显,在代码层次上来说,使代码变得非常的简洁。缺点也很明显,代码不易读。优点:简洁性:Lambda表达式可以大大简化代码,减少样板代码的编写,提高代码的简洁性。函数式编程:Lambda表达式支持函数式编程,可以方便地进行函数组合、高阶函数等操作,使代码更加灵活和易于理解。并行处理:Lambda表达式可以方便地与并行处理结合,可以更容易地实现并行操作,提高程序的性能。Java 引入 Lambda,改善了集合操作代码复用:Lambda表达式可以实现函数的复用。

2024-04-12 22:02:10 1036

原创 表白墙系统测试

提高测试效率:自动化测试可以快速执行测试用例,比手动测试更高效。只创建一次驱动对象,避免每个用例重复创建驱动对象造成时间和资源的浪费。使用参数化:保持用例的简洁,提高代码的可读性。使用测试套件:降低了测试人员的工作量,通过套件一次执行所有要运行的测试用例。使用了等待:提高了自动化的运行效率,提高了自动化的稳定性,减小误报的可能性。使用了Junit5中提供的注解:避免生成过多的对象,造成资源和时间的浪费,提高了自动化的执行效率。

2024-04-07 14:48:18 1089

原创 数据结构-----反射

Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射(reflection)机制。Java反射是Java编程语言的一个重要特性,它允许程序在运行时动态地获取类的信息、调用类的方法、访问类的属性等。Java反射的意义在于:动态加载类:Java反射可以在运行时动态加载和实例化类。

2024-03-02 15:12:41 715

原创 数据结构-----再谈String,字符串常量池,String对象的创建、intern方法的作用

例如,如果在程序中大量使用字符串常量拼接,每次拼接都会生成一个新的String对象,这种情况下使用StringBuilder或StringBuffer等可变字符串类更合适,因为它们可以避免创建过多临时的String对象。提高效率:由于字符串常量池中的对象是可复用的,当需要创建相同内容的字符串时,可以直接引用常量池中的对象,避免了对象的重复创建和销毁过程,从而提高了程序的执行效率。在Java程序中,类似于:1, 2, 3,3.14,“hello”等字面类型的常量经常频繁使用,为了使程序的运行。

2024-02-29 16:14:33 960

原创 数据结构-----二叉搜索树、模拟实现二叉搜索树、Map、Set的使用以及说明、哈希表的概念以及冲突避免的方法、哈希桶的实现、HashMap源码解析、相关OJ练习题

这是因为,当两个对象的内容相同时,它们应该具有相同的哈希码。插入和查找操作的时间复杂度为O(1):虽然哈希表一直在和冲突做斗争,但在实际使用过程中,我们认为哈希表的冲突率是不高的,冲突个数是可控的,也就是每个桶中的链表的长度是一个常数,所以,通常意义下,我们认为哈希表的插入/删除/查找时间复杂度是O(1)。(3) 另外,TreeSet和HashSet的迭代顺序也是不同的,TreeSet的迭代顺序是根据元素的排序顺序,而HashSet的迭代顺序是不确定的,可能会受到散列表的扩容和哈希冲突等因素的影响。

2024-02-29 16:14:09 973

原创 数据结构-----排序的概念、常见排序的实现以及排序算法的特点、非比较排序、排序相关例题

快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序时间复杂度:O(N*logN)空间复杂度:O(logN)稳定性:不稳定归并的缺点在于需要O(N)的空间复杂度,也就是说,申请的临时数组和原数组一模一样,归并排序的思考更多的是解决在磁盘中的外排序问题。时间复杂度:O(N*logN)空间复杂度:O(N),主要用于存储临时的合并结果。在归并排序过程中,需要额外的O(N)的空间来存储合并操作的中间结果,因此相对于快速排序等原地排序算法,归并排序的空间复杂度较高。

2024-02-27 13:20:01 786

原创 数据结构-----优先级队列的概念、模拟实现、特性、常用方法、扩容机制、初始化、堆的应用、Top-K问题

Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,本文主要介绍PriorityQueue。使用时必须导入PriorityQueue所在的包,即:PriorityQueue中放置的元素必须要能够比较大小,不能插入无法比较大小的对象,否则会抛出ClassCastException异常.

2024-02-27 13:19:34 974

原创 数据结构-----树形结构、二叉树的介绍

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。根节点(Root):树中的一个特殊节点,它没有前驱节点,是整个树的起点。子树(Subtree):除根节点外,树中的每个节点都可以看作是一棵子树的根节点。子树是一棵与原树类似的树,它包含了一部分原树中的节点和边。前驱节点(Parent)和后继节点(Children):一个节点的前驱节点是其所在子树的根节点,而该节点称为前驱节点的后继节点。

2024-02-15 16:14:42 819

原创 力扣例题----二叉树

【题目链接】:100.相同的树【题目描述】:给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。【解题过程】:两个二叉树相同,当且仅当两个二叉树的结构完全相同,且所有对应节点的值相同。让两个指针一开始先指向两棵二叉树的根节点,然后同步移动两根指针来同步遍历这两棵树,判断对应位置是否相等。算法实现步骤:【代码】:复杂度分析:【时间复杂度】:O(min⁡(m,n)),其中 m 和 n分别是两个二叉树的节点数

2024-02-15 16:13:44 1052

原创 数据结构----队列(Queue)的概念、队列的使用、模拟实现队列、循环队列、模拟实现循环队列、双端队列、模拟实现双端队列

思路:借用辅助栈来实现,入队时将所有入队的元素放入辅助栈(stack1),出队时如果栈(stack2)不为空,那么就从栈(stack2)中读取数据,如果栈(stack2)为空,将辅助栈(stack1)中所有数据颠倒放入栈(stack2)中,再从栈(stack2)中读取数据。循环队列通常包含两个指针,一个指向队列的头部(front),一个指向队列的尾部(rear)。如果rear的下一个元素为front,即为(rear+1)%array.length = front,那么队列就是满的。

2024-02-03 18:15:36 2093

原创 数据结构----栈的概念、模拟实现、栈的使用、栈的应用、有关栈的算法题

例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。当一个方法被调用时,会在虚拟机栈中创建一个新的栈帧,当方法执行结束时,栈帧会被销毁。虚拟机栈:虚拟机栈是指在计算机中运行的程序中,每个线程都有自己的虚拟机栈,用于存储线程中方法的局部变量、操作数栈、动态链接、返回地址等信息。答案:为C,C选项中先出的元素为3,说明之前入栈的元素为1、2、3,3出栈之后,出栈顺序一定是2在1之前,2不出来,1不可能先出来。

2024-02-03 17:44:14 962

原创 数据结构----链表介绍、模拟实现链表、链表的使用

链表是一种常见的数据结构,它由一系列节点组成,每个节点包含两部分:数据元素 (value) 和指向下一个节点的指针 ( next 域 )。通过这些节点的连接,可以形成一个链式结构。【单个节点】:节点(Node):链表的基本单元,包含数据域和next指针域。数据域可以是任意类型的数据,指针指向下一个节点。每个节点都是一个对象。【节点组成的链式结构】:结论: 链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的。LinkedList 的官方文档。

2024-01-29 19:40:52 1143

原创 数据结构----ArrayList的简介、使用、扩容机制、使用ArrayList实现杨辉三角

在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:【说明】ArrayList是以泛型方式实现的,使用时必须要先实例化ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问ArrayList实现了Cloneable接口,表明ArrayList是可以clone的ArrayList实现了Serializable接口,表明ArrayList是支持序列化的。

2024-01-29 19:39:54 925

原创 力扣、牛客例题-----链表

并且题目中提到不能改变原来的数据顺序,所以。

2024-01-28 10:19:45 2192

原创 数据结构----线性表、顺序表、模拟实现顺序表

返回的数组类型与源数组类型相同。线性表是一种在实际中广泛使用的数据结构,指具有相同数据类型的元素按照一定的顺序排列的数据结构,其中每个元素都有唯一的前驱元素和后继元素(除了第一个元素没有前驱,最后一个元素没有后继),常见的线性表:顺序表、链表、栈、队列…顺序表是一种线性表的存储结构,它是由一组地址连续的存储单元依次存储线性表中的元素,元素之间的逻辑关系和物理关系是一致的。如果里面的每一个元素都是引用类型,需要使用equals()来进行比较,如果是自定义类型,还需要自己覆盖equals()方法。

2024-01-24 09:32:19 730

原创 数据结构----List简介

List 接口是 ArrayList 类的一个父接口,通过使用 List 类型的引用来指向 ArrayList 对象,可以使代码更具有通用性。这样写的好处是,以后如果需要更改为其他类型的 List(如 LinkedList),只需要改变声明的时候的类型,而不需要修改实例化的代码。List是Java集合框架中的一个接口,它表示一个有序的、可重复的元素集合。List的灵活性和功能丰富性使得它成为Java中常用的集合类型之一,可以方便地操作和管理有序的元素集合。如果要使用,必须去实例化List的实现类。

2024-01-24 09:32:00 883

原创 数据结构----集合框架的简单介绍

数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。算法(Algorithm):就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果。

2024-01-22 17:42:19 734

原创 数据结构----基本封装、包装类、装箱与拆箱、泛型详解

由于类型擦除,编译器无法检查类型转换的正确性,返回的Object数组里面,可能存放的是任何的数据类型,可能是String,可能是Person,运行的时候,直接转给Object类型的数组,编译器认为是不安全的。在泛型的擦除过程中,泛型类型参数被替换为其上界或Object类型,因此在编译时无法确定具体的泛型类型。而c和d的值都不在[-128, 127]之间,因此它们不会被缓存起来,每次自动装箱时都会创建一个新的Integer对象,所以c和d指向的不同对象,因此c==d的结果为false。

2024-01-22 17:40:50 1067

原创 JAVA基础----String类型的简单介绍

由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilder和StringBuffer类。这两个类大部分功能是相同的,不同点是StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作,这里介绍 StringBuilder常用的一些方法,其它需要用到了大家可参阅StringBuilder在线文档方法说明。

2024-01-18 21:09:47 820

原创 JAVA基础-----认识异常

Java 中虽然已经内置了丰富的异常类, 但是并不能完全表示实际开发中所遇到的一些异常,此时就需要维护符合我们实际情况的异常结构.例如, 我们实现一个用户登陆功能.if (!if (!System.out.println("登陆成功");

2024-01-18 21:09:35 999

原创 JAVA基础---抽象类和接口

包含抽象方法的类(Animal类)我们称为。

2024-01-16 16:29:15 873

原创 JAVA基础---内部类详解

内部类也是封装的一种体现。

2024-01-16 16:28:49 906

原创 继承和多态的详解

即外壳不变,核心重写!上述图示中,Dog和Cat都继承了Animal类,其中:Animal类称为父类/基类或超类,Dog和Cat可以称为Animal的子类/派生类,继承之后,子类可以复用父类中成员,子类在实现时只需关心自己新增加的成员即可。指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系。:也称为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用那个类的方法。

2024-01-10 00:07:04 740

原创 代码块的分类和执行顺序

使用 {} 定义的一段代码称为代码块。如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行。构造块:定义在类中的代码块(不加修饰符)。1、父类静态代码块优先于子类静态代码块执行,且是最早执行。3、子类的实例代码块和子类构造方法紧接着再执行。使用static定义的代码块称为静态代码块。静态代码块不管生成多少个对象,其只会执行一次。2、父类实例代码块和父类构造方法紧接着执行。普通代码块:定义在方法中的代码块.

2024-01-08 20:30:47 358

原创 类和对象的定义以及使用

面向对象程序设计关注的是对象,而对象是现实生活中的实体,比如:狗。但是狗计算机并不认识,需要开发人员告诉给计算机什么是狗。上图右侧就是对狗简单的描述,该过程称为对狗对象(实体)进行抽象(对一个复杂事物的重新认知),但是这些简化的抽象结果计算机也不能识别,开发人员可以采用某种面向对象的编程语言来进行描述,比如:Java语言。在java中定义类时需要用到class关键字,class为定义类的关键字,ClassName为类的名字,{}中为类的主体。// 创建类field;// 字段(属性) 或者 成员变量。

2024-01-08 18:02:40 1099

原创 数组的定义与使用

总结: 所谓的 “引用” 本质上只是存了一个地址. Java 将数组设定成引用类型, 这样的话后续进行数组参数传参, 其实只是将数组的地址传入到函数形参中. 这样可以避免对整个数组的拷贝(数组可能比较长, 那么拷贝开销就会很大).所谓 “遍历” 是指将数组中的所有元素都访问一遍, 访问是指对数组中的元素进行某种操作,比如:打印。array是数组类型的引用变量,其内部保存的内容可以简单理解成是数组在堆空间中的首地址。通过观察代码可以发现,对数组中每个元素的操作都是相同的,则可以使用循环来进行打印。

2024-01-06 19:52:17 971 1

原创 方法的使用以及递归的介绍

方法就是一个代码片段. 类似于 C 语言中的 “函数”。是能够模块化的组织代码(当代码规模比较复杂的时候).做到代码被重复使用, 一份代码可以在多个位置使用.让代码更好理解更简单.直接调用现有方法开发, 不必重复造轮子.方法语法格式// 方法定义修饰符 返回值类型 方法名称([参数类型 形参 ...]){方法体代码;[return 返回值];代码示例:实现一个函数,检测一个年份是否为闰年// 方法定义}else{【注意事项】

2024-01-06 18:18:38 740 1

原创 计算数字二进制中1的个数:求一个整数,在内存当中存储时,二进制1的个数。

第一种方式的缺陷:不管是什么数据,循环都要执行32次。比如数字7:0000 0111 右移3次之后,就是0了。此种方式,数据的二进制比特位中有几个1,循环就循环几次,而且中间采用了位运算,处理起来比较高效。第一次循环:n=7 n=n&(n-1) = 7 & 6 = 6。第二次循环:n=6 n=n&(n-1)= 6 & 5= 4。第三次循环:n=4 n=n&(n-1)=4 & 3= 0。只需让这一位和1进行按位与即可。

2024-01-04 14:21:22 387 1

原创 逻辑控制使用

逻辑控制有三种结构:顺序、选择、循环结构。

2024-01-04 13:58:29 2312 1

原创 JAVA运算符以及运算符的优先级(详解)

上述 + 和 < 等就是运算符,即:对操作数进行操作时的符号,不同运算符操作的含义不同。作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。Java中运算符可分为以下:算术运算符(+ - * /)、关系运算符(< > ==)、逻辑运算符、位运算符、移位运算符以及条件运算符等。

2023-12-31 14:06:42 1005 1

原创 数据类型与变量

byte 和 byte 都是相同类型, 但是出现编译报错. 原因是, 虽然 a 和 b 都是 byte, 但是计算 a + b 会先将 a和 b 都提升成 int, 再进行计算, 得到的结果也是 int, 这时赋给 c, 就会出现上述错误.在程序中,除了有始终不变的常量外,有些内容可能会经常改变,比如:人的年龄、身高、成绩分数、数学函数的计算结果等,对于这些经常改变的内容,在Java程序中,称为。Java 作为一个强类型编程语言, 当不同类型之间的变量相互赋值的时候, 会有教严格的校验.

2023-12-30 10:31:36 936 1

原创 模拟实现offsetof

3. 经过上面的分析之后,这段代码的逻辑就很简单了,通过 &((TYPE *)0)->MEMBER) 先取 TYPE 结构体类型成员的地址,强制转换成 size_t 类型后返回结构体类型成员的地址。1. (type *)0,可以理解为把 0 地址强制转换为 type 结构体类型的指针,此时 0 就成了 type 结构体的首地址,指向该结构体,既然为结构体指针,那么自然可以引用该结构体的成员,所以 (type *)0)->member 的整体意义就是引用 type 结构体的成员 member。

2023-12-27 12:53:21 358 1

原创 模拟实现atoi

atoi的规则是:跳过不可见字符,碰到负号或者数字开始转换,转换到非数字字符为止。

2023-12-27 11:12:50 355 1

原创 找单身狗(异或的使用)

同理,在数组中也可以使用异或的方式,将数组所有元素进行异或运算得到的结果.比如一个数组:[1,2,3,4,5,4,3,2,1],则该数组的异或和为:1^2^3^4^5^4^3^2^1.由于,相同的数字异或结果为0,0和任何数异或的结果为该数本身,当我们求出第一个数之后,可以对数组异或的结果和第一个单身狗进行异或,可以求出第二个单身狗。一个数组中只有一个数字是出现一次,其他所有数字都出现了两次。有数组的元素是:1,2,3,4,5,1,2,3,4,6。有数组的元素是:1,2,3,4,5,1,2,3,4。

2023-12-27 10:15:45 334 1

原创 程序环境和预处理

_FILE__ //进行编译的源文件__LINE__ //文件当前的行号__DATE__ //文件被编译的日期__TIME__ //文件被编译的时间__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义 (VS不支持)这些预定义符号都是语言内置的。语法:#define reg register //为 register这个关键字,创建一个简短的名字;) //用更形象的符号来替换一种实现。

2023-12-26 19:08:49 959 1

原创 C语言文件操作

磁盘上的文件是文件。但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件(从文件功能的角度来分类的)。程序文件:包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。数据文件:文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上文件。

2023-12-24 12:05:14 771 1

原创 柔性数组的使用以及优势

所以,如果我们把结构体的内存以及其成员要的内存一次性分配好 了,并返回给用户一个结构体指针,用户做一次free。如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给 用户。函数进行内存的动态分配,并且分配的内存应该大于结构的大 小,以适应柔性数组的预期大小。C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。输出的结果为4,因为结构大小不包括柔性数组的大小。返回的这种结构大小不包括柔性数组的内存。就可以把所有的内存也给释放掉。

2023-12-22 22:01:54 337

空空如也

空空如也

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

TA关注的人

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