- 博客(58)
- 资源 (1)
- 收藏
- 关注
原创 为什么HashMap线程不安全?以及实现HashMap线程安全的解决方案
一、为什么HashMap线程不安全?1、JDK1.7 扩容引发的死循环和数据丢失(1).当前jdk1.7版本的HashMap线程不安全主要是发生在扩容函数中,其中调用了HshMap的transfer()方法//jdk 1.7的transfer方法,HashMap的扩容操作void transfer(Entry[] newTable, boolean rehash) { int newCapacity = newTable.length; for (Entry<K,V> e
2021-09-03 01:10:52
12850
5
原创 List、Set和Map接口实现类的底层源码分析
一、List接口存储有序的、可重复的数据。“动态”数组, 替换原有的数组1.ArrayListArraylist:作为ist接口的主要实现类;线程不安全,效率高,底层使用Object[ ]顺序存储private transient Object[ ] elementData;1.1.ArrayList在jdk7源码分析ArrayList list = new ArrayList();底层创建长度是10的Object[]数组elementData(饿汉式)public ArrayLis
2021-09-01 21:06:46
661
2
原创 设计模式-工厂模式
工厂模式-核心本质:◆实例化对象不使用new,用工厂方法代替◆将选择实现类,创建对象统一管理和控制。 从而将调用者跟我们的实现类解耦。◆抽象工厂模式围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。1.简单工厂模式对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象。用来生产同一等级结构中的任意产品(对于增加新的产品,需要覆盖已有代码)其UML类图如下:汽车生产案例Car类:汽车标准规范类(AbstractProduct)publ
2021-08-27 17:25:32
374
原创 多线程进阶-JUC并发编程(下篇)
十五、异步回调1.什么是异步回调?同步回调和异步回调, 主要体现在其是否需要等待.同步调用,:如果C处理一个问题需要花很长时间, 我们需要等待这个问题处理完,再继续执行其他任务。异步调用:如果C处理这个需要等待的问题时不需要等待得到结果, 而是扔给S去处理,C然后接着,去做其他事情。2.CompletableFuture-异步回调CompletableFuture在Java里面被用于异步编程,异步通常意味着非阻塞,可以使得我们的任务单独运行在与主线程分离的其他线程中,并且通过回调可以在主线程
2021-08-26 23:39:18
318
原创 多线程进阶-JUC并发编程(中)
九、读写锁要求:实现可以多次读取,但只能一次修改数据1.自定义缓存,没有加锁public class ReadWriteLockDemo { public static void main(String[] args){ MyCache myCache = new MyCache(); //写入 for (int i = 1; i <= 5; i++) { //lambda内部获取不到外部的i需要借助中间变量
2021-08-25 21:31:36
213
原创 多线程进阶-JUC并发编程(上篇)
一、JUC1.JUC相关知识点汇总2.什么是JUCJUC:java.util.concurrent包名的简写,是关于并发编程的API。与JUC相关的有三个包:java.util.concurrent、java.util.concurrent.atomic、java.util.concurrent.locks。二、进程与线程1、进程与线程进程:程序的一次执行过程,是系统运行的基本单位,因此进程是动态的(很多次执行)。系统运行一个程序是一个进程创建、运行到消亡的过程。在JAVA中,当我们启动M
2021-08-24 18:50:49
358
原创 JavaWeb-Listener监听器、Filter过滤器和JSON
一、Listener监听器1.什么是Listener监听器?(1)、Listener 监听器它是JavaWeb的三大组件之一。JavaWeb 的三大组件分别是: Servlet 程序、Filter 过滤器、Listener 监听器。(2)、Listener 它是JavaEE的规范,就是接口(3)、监听器的作用是,监听某种事物的变化。然后通过回调函数,反馈给客户(程序)去做一些相应的处理。2.ServletContextListener监听器(1)ServletContextListener它可以
2021-08-09 17:02:26
234
原创 JavaWeb-servlet、cookie和session
一、Servlet技术1.什么是Servlet(1)、Servlet 是JavaEE规范之一。 规范就是接口(2)、Servlet 就JavaWeb三大组件之一。 三大组件分别是: Servlet 程序、Filter 过滤器、Listener 监听器。(3)、Servlet 是运行在服务器上的一个java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。2.手动实现Servlet程序(1)、编写一个类去实现Servlet接口(2)、实现service方法,处理请求,并响应数据pa
2021-08-08 18:13:42
255
原创 Spring5-IOC、AOP、事务管理
笔记整理来源于尚硅谷,仅供本人复习使用,无其它目的一、Spring框架概述1、Spring 是轻量级的开源的JavaEE框架。2、Spring可以解决企业应用开发的复杂性。3、Spring 有两个核心部分: IOC 和Aop.(1) IOC: 控制反转,把创建对象过程交给Spring进行管理,(2) Aop:面向切面,不修改源代码进行功能增强。4、Spring 特点(1)方便解耦,简化开发(2) Aop编程支持。(3)方便程序测试。(4)方便和其他框架进行整合。(5)方便进行事务操作
2021-08-07 13:40:48
405
1
原创 Java中的常量池(字符串常量池、class常量池和运行时常量池)
笔记整理来源于zhuminChosen,仅供本人复习使用一、字符串常量池(String Constant Pool)1.字符串常量池在Java内存区域的哪个位置?➢JDK6.0及之前版本,字符串常量池是放在Perm Gen区(也就是方法区)中;➢JDK7.0版本,字符串常量池被移到了堆中了。至于为什么移到堆内,大概是由于方法区的内存空间太小了。2.字符串常量池是什么?➢在HotSpot VM里实现的string pool功能的是一个StringTable类,它是一个Hash表,默认值大小长度是1
2021-07-09 16:17:23
215
原创 JVM-GC、垃圾回收算法和finalization机制
笔记均来自于尚硅谷官方视频,为了本人复习使用,无其他目的尚硅谷官方视频一、什么是垃圾?垃圾是指在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。通俗讲就是对象使用完,不再继续使用!二、为什么要进行垃圾回收(GC)1.释放没用的对象,如果不进行垃圾回收,内存迟早都会被消耗完,而且这些垃圾对象所占的内存空间会一直保留到应用程序结束,被保留的空间无法被其他对象使用,甚至可能导致内存溢出。2.垃圾回收也可以清除内存里的记录碎片,碎片整理将所占用的堆内存移到堆的一端,以便JVM将整理出的内
2021-07-09 16:04:13
322
1
原创 JVM-直接内存和执行引擎
一、直接内存1.不是虛拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。2.直接内存是在Java堆外的、直接向系统申请的内存区间。来源于NIO,通过存在堆中的DirectByteBuffer操作Native内存,3.访问直接内存的速度会优于Java堆。即读写性能高,适用于读写频繁以及大文件的场合。Java的NIO库(非阻塞)允许Java程序使用直接内存4.由于直接内存在Java堆外,因此它的大小不会直接受限于-Xmx指定的最大堆大小,但是系统内存是有限的,Java堆和
2021-07-08 14:47:53
120
原创 JVM-对象的实例化内存布局与访问定位
笔记均来自于尚硅谷官方视频,为了本人复习使用,无其他目的尚硅谷官方视频一、对象的实例化1.创建对象的方式1). 使用new关键字创建对象这是我们最常见的也是最简单的创建对象的方式,通过这种方式我们可以调用任意的构造函数(无参的和有参的)去创建对象。比如:Student stu1 = new Student(123);2). 使用Class类的newInstance方法(反射机制)我们也可以通过Java的反射机制使用Class类的newInstance方法来创建对象,事实上,这个newIns
2021-07-07 11:55:52
79
原创 JVM内存模型-方法区和垃圾回收
笔记均来自于尚硅谷官方视频,为了复习,无其他目的视频笔记来源一、 堆、栈、方法区的交互关系1.运行时数据区结构图2.堆、栈、方法区的交互关系注意:局部变量表中的对象引用指向堆空间中的实体,堆空间中有对象类型数据指针指向方法区中的对象类型数据,即对象是哪个类new的。只要是对象实例必然会在Java堆中分配。二、方法区的理解1.方法区可以看作是一块独立于Java堆的内存空间。2.方法区(Method Area)与Java堆一样,是各个线程共享的内存区域3.方法区在JVM启动时就会被创建
2021-06-16 10:38:00
220
原创 JVM-堆空间内存分配和各区垃圾回收
一、堆的简介(1)一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域。(2)Java 堆区在JVM启动的时候即被创建,其空间大小也就确定了。是JVM管理的最大的一块内存空间。(3)堆内存的大小是可以调节的。堆可以处于物理上不连续的内存空间中,但在逻辑上它应该被视为连续的。(4)所有的线程共享Java堆,在这里还可以划分线程私有的缓冲区(ThreadLocal Allocation Buffer, TLAB) 。几乎所有的对象实例以及数组都应当在运行时分配在堆上(5)数组和对象可能永
2021-06-10 15:44:48
612
2
原创 JVM线程私有-程序计数器、虚拟机栈和本地方法栈
一、PC寄存器(程序计数器)1.PC寄存器简介:PC寄存器,也叫程序计数器,是块很小的内存空间,几乎可以忽略不记。也是运行速度最快的存储区域。在JVM规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致。任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址;或者如果是在执行native方法,则是未指定值(undefned)。2.PC寄存器的作用:PC寄存器用来存储指向下一条指令的地址(偏移地址
2021-06-08 21:37:17
930
原创 JVM类加载器子系统-双亲委派机制
一、加载器分类和简介JVM支持两种类型的类加载器,分别为引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader);后面提到的扩展加载器和系统加载器因为都间接继承于ClassLoader,所以都是自定义加载器从概念上来讲,自定义类加载器一般指的是程序中由开发人员自定义的一类类加载器,但是Java虚拟机规范却没有这么定义,而是将所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器。无论类加载器的类型如何划分,在程序中
2021-06-04 14:40:22
146
2
原创 堆排序-heapSort
一、堆排序简介堆排序基本介绍1)堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为0(nlogn),它也是不稳定排序。2)堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆,注意:没有要求结点的左孩子的值和右孩子的值的大小关系。3)每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆堆排序的基本思想:1)将待排序序列构造成一个大顶堆2)此时, 整个序列的最大值就是堆顶的根节点。3)将其与末尾元素进行交换
2021-06-03 14:29:58
132
原创 线索化二叉树-实现中序遍历和查找前驱后继节点
一、线索化二叉树简介1.线索二叉树:对于n个节点的二叉树,在二叉链存储结构中有n+1个空链域,利用这些空链域存放在某种遍历次序下该节点的前驱节点和后继节点的指针,这些指针称为线索,加上线索的二叉树称为线索二叉树2.线索二叉树分类:这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种。3.前驱结点:一个结点的前一个结点4. 后继结点:一个结点的后一个结点二、中序线索化二叉树逻辑结构示意图说明:当线
2021-06-02 20:26:40
1341
原创 二叉树顺序存储-实现前序中序后序遍历
一、顺序存储二叉树简介二叉树的存储结构有两种,分别为顺序存储和链式存储。二叉树的顺序存储,指的是使用顺序表(数组)存储二叉树。只有完全二叉树才可以使用顺序表存储。因此,如果我们想顺序存储普通二叉树,需要提前将普通二叉树转化为完全二叉树。从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组,逻辑示意图如下二、代码实现要求:给定已知数组{1,2,3,4,5,6,7},要求以二叉树前序,中序,后续遍历的方式进行遍历,达到如下结果。前序遍历:1,2,4,5,3
2021-06-01 21:05:15
1773
原创 二叉树-前序中序后续遍历,以及查找删除操作!
一、二叉树的介绍1.二叉树:每个节点最多只能有两个子节点的一种形式的树2.左右节点:也叫孩子节点,二叉树的子节点分为左节点和右节点,如图21为11的左子节点,31为11的右子节点,11为21和31的父节点3.叶子节点:叶子节点就是树中最底段的节点,叶子节点没有子节点。4.满二叉树:二叉树的所有叶子节点都在最后一层,并且满足节点总数为2^(n-1),n为层数。5.完全二叉树:二叉树的所有叶子节点都在最后一层或者分布在倒数第二层,并且满足最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连
2021-06-01 15:32:14
259
原创 哈希表-实现节点员工信息的增删改操作
一、哈希表的基本介绍散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一-个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。数组的特点是:寻址容易,插入和删除困难;而链表的特点是:寻址困难,插入和删除容易。综合两者的特性,做出一种寻址容易,插入删除就用到了哈希表,哈希表最常用的一种方法就是拉链发,即数组加链表二、哈希表实现员工案例逻辑示意图三、代码实现和结果
2021-05-31 19:56:41
284
原创 查找-插值查找InsertValueSearch
一、插值查找简介插值查找,有序表的一种查找方式。插值查找是根据查找关键字与查找表中最大最小记录关键字比较后的查找方法。插值查找基于二分查找,将查找点的选择改进为自适应选择,提高查找效率。原理分析1)插值查找每次从自适应mid处开始查找2)将折半查找中的求mid索引的公式,low表示左边索引,high表示右边索引int mid =(low+high)/2= low + (high- low) /2 改为int mid = low + (high- low) * (findValue- arr[lo
2021-05-30 16:42:46
148
原创 查找-线性查找
一、线性查找思想线性查找又称顺序查找,是一种最简单的查找方法,它的基本思想是从第一个记录开始,逐个比较记录的关键字,直到和给定的value值相等,则查找成功;若比较结果与数组中arr.length个记录的关键字都不等,则查找失败二、代码实现与截图键入式package search;import java.util.Scanner;public class ArrayListSearch { public static void main(String[] args) {
2021-05-30 15:39:03
156
原创 查找-二分查找BinarySearch
一、二分查找的思路要使用二分查找,首先要确保已知数组是有序的1.首先确定该数组的中间的下标 mid= (left+right) / 22.然后让需要查找的数findvalue和arr[mid]比较2.1 findvalue >arr[mid],说明你要查找的数在mid的右边,因此需要递归的向右查找2.2 findvalue<arr[mid],说明你要查找的数在mid的左边,因此需要递归的向左查找2.3 findvalue ==arr[mid]说明找到,就返回3.结束递归1)找到就
2021-05-30 15:31:04
133
原创 排序-基数排序RadixSort
一、基数排序(桶排序)介绍:1)基数排序(radixsort)属于“分配式排序”(distributionsort) ,又称“桶子法”(bucket sort)或binsort,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用.2)基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法3)基数排序(Raditsort)是桶排序的扩展4)基数排序是1887年赫尔曼.何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。二、基数排序逻辑
2021-05-28 14:18:16
1068
原创 排序-归并排序MergeSort
1.归并排序简介归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。2.归并操作归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。如 设有数列{6,202,100,301,38,8,1}初始状态:6,202,100,301,38,8,
2021-05-27 20:45:05
583
原创 数组实现栈
一、栈的特点1.栈的介绍①栈的英文为(stack)②栈是一个先进后出(FILO-First In Last Out)的有序列表。③栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端,为变化的一端,称为栈顶(Top), 另一端为固定的一 端,称为栈底(Bottom)。④根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除2.入栈逻辑结构示意图入栈的操作,当有数
2021-05-27 20:06:05
62
原创 单项链表和双向链表-实现英雄节点的增删改操作
一、单项链表单向链表逻辑结构意图1.定义一个英雄节点类//定义一个HeroNode,每个HeroNode对象就是一个节点class HeroNode{ public int no;//编号 public String name ;//姓名 public String nickName ;//昵称 public HeroNode next;//next指向下一个节点 //构造器 public HeroNode(int no, String nam
2021-05-27 18:35:58
152
原创 数组实现队列和环形队列
一、队列特点:先进先出,就像排队,先来的先办理服务原理①初始化一个队列类,定义他的属性(队列的最大长度,队头位置,对尾位置,数组)②初始化队头位置为-1,对尾位置为-1。不能定义为0,是因为数组的索引值是从0开始的,定义为0则表示队列(数组)在开始就存在一个值, 所以不这样定义。③然后初始化队列的长度,当添加的时候,移动对尾位置 ,rear++, 当取数据的时候,移动队头位置,front++。// 定义一个数组模拟队列的类class ArrayQueue{ private int
2021-05-24 09:07:11
86
原创 排序-快速排序QuickSort
快排思想:1.找到任意找一个基准值,2.然后将左边的值总体小于基准,右边的值总体大于基准,3.然后左右两边继续递归执行1.2方法package sort;import java.util.Arrays;import java.util.Scanner;public class QuickSort { public static void main(String[] args){ Scanner scanner = new Scanner(System.in);
2021-05-15 23:22:40
111
原创 排序-希尔排序ShellSort
简单来说,就是先确定增量,按增量分组,并逐步缩小增量,对各组中的元素进行插入排序package sort;import java.util.Arrays;import java.util.Random;import java.util.Scanner;public class ShellSort { public static void sort(int[] arr){ //定义一个num用来记录轮数 int num = 0; //ga
2021-05-15 23:17:41
77
原创 排序-插入排序InsertSort
一、排序原理二、代码实现package sort;import java.util.Arrays;import java.util.Scanner;/** * 排序原理: * 1.把所有的元素分为两组,已经排序的和未排序的; * 2.找到未排序的组中的第一个元素 ,向已经排序的组中进行插入; * 3.倒叙遍历已经排序的元素,依次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那么就把待插入元素放到这个 * 位置,其他的元素向后移动一位; */public class
2021-05-14 21:43:06
105
原创 排序-选择排序SelectSort
一、选择排序思路二、逐步推导选择排序package sort;import java.util.Arrays;public class SelectSort { //选择排序时间复杂度为O(n2) public static void main(String[] args){ int arr[] = {101,34, 119, 1}; System.out.println("原始的数组:"+ Arrays.toString(arr));
2021-05-13 00:05:40
102
原创 排序-冒泡排序BubbleSort
一、冒泡排序(常规实现)package Bubble;import java.util.Arrays;import java.util.Scanner;public class Bubble { public static void main(String[] args){ Scanner scanner = new Scanner(System.in); System.out.println("请输入排序数组长度:"); int n
2021-05-12 22:38:46
91
原创 多线程-多线程创建和安全问题的解决
一、多线程的创建方式一:继承Thread步骤:1.创建一个继承于Thread类的于类2.重写Thread类的run(),方法体写要做的事3.创建Thread类的子类的对象4.通过此对象调用start():①启动当前线程②调用当前线程的run()方法案例:如主线程查询10以内所有的奇数,分线程0查询10以内所有的偶数,分线程1输出hello worldpublic class MyThreadTest { public static void main(String[] args){
2021-05-09 17:34:58
169
原创 枚举类Enum
一、枚举类的使用1.枚举类的理解:类的对象只有有限个,确定的。我们称此类为枚举类2.当需要定义一组常量时,强烈建议使用枚举类3.如果枚举类中只有一个对象,则可以作为单例模式的实现方式。二、如何定义枚举类方式一: jdk5.0之前, 自定义枚举类public class EnumTest { //自定义枚举类 static class Season{ //1.声明Season对象的属性:private final 修饰 private fina
2021-04-28 14:31:40
89
原创 JDBC-数据库连接及增删改操作
一、数据库连接方式一:反射加载驱动,自动注册package JDBC;import java.sql.DriverManager;public class Connection { public static void main(String[] args) throws Exception{ //1.提供三个基本信息 String url = "jdbc:mysql://localhost:3306/goutong" ; String u
2021-04-24 16:28:26
284
原创 MySQL -DDL数据定义语言
DDL数据定义语言一、库的管理1、库的创建/*语法:加容错性判断creat database [if not exists] 库名;*/#eg:create database if not exists books;create database if not exists students;2、库的修改/*更改库名rename database books to 新库名;不安全被废除*/#更改字符集alter database books character set gb
2021-04-19 15:03:06
98
原创 MySQL -DML数据操作语言
DML语言数据操作语言:插入: insert修改: update删除: delete一、插入语句方式一:语法:insert into 表名(列名…)values(值1, …);特点:支持插入多行,支持查询子集SELECT * FROM beauty; 1.插入的值的类型要与列的类型一致或兼容INSERT INTO beauty (id, NAME, sex, borndate, phone , photo, boyfriend_id)VALUES(13, '唐艺昕', '女',
2021-04-19 14:38:44
136
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人