自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 IO复用模型

进程与线程的描述一个进程至少会创建一个线程,多个线程共享一个程序进程的内存。程序的运行最终是靠线程来完成操作的。线程的数量跟CPU核数有关,一个核最多能发出两个线程。线程的操作主要分为:一:给CPU进行程序命令的执行。二:IO的操作(读取或输出数据)或者请求网络数据。IO复用形成原因如果一个I/O流进来,我们就开启一个进程处理这个I/O流。那么假设现在有一百万个I/O流进来,那我们就需要开启一百万个进程一一对应处理这些I/O流(——这就是传统意义下的多进程并发处理)。思考一下,一百万个进程,你的

2021-09-04 20:39:58 640

原创 数据库大表优化

1.HasMap基础key-value形式用key做hash定位 整个将k和v存储到对应位置2.解决hash冲突方法拉链法开放地址法3.jdk1.7和1.8的区别1.7头插法hash()->4次扰动先扩容再插入数组+链表1.8尾插法hash()->1次扰动数组+链表/红黑树当前链表长度>=8 数组长度>64先插入再扩容4. jdk1.8HashMap插入原理判断数组是否为空,为空进行初始化;不为空的,计算插入

2021-09-04 16:22:23 279

原创 java的动态绑定

Java的动态绑定又称为运行时绑定。即在程序运行过程中,根据具体的实例对象才能具体确定是哪个方法。 意思就是说,程序会在运行的时候自动选择调用那个方法。二、Demo  1. 子类重写父类中的方法,调用子类中的方法public class Father{ public void method(){ System.out.println("父类方法:"+this.getClass()); }}public class Son extends Father{

2021-08-28 20:12:17 797

原创 java中的包装类型

包装类型Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。包装类均位于java.lang包,包装类和基本数据类型的对应关系如下表所示基本数据类型 包装类 byte Byte boolean Boolean short Short char Char

2021-08-28 19:48:29 326

原创 最大子序和

给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。示例 1:输入:nums = [-2,1,-3,4,-1,2,1,-5,4]输出:6解释:连续子数组[4,-1,2,1] 的和最大,为6 。来源:力扣(LeetCode)几个连续数字相加越来越大,首先能想到一种情况全是正数,但是题中正负都有,所以在加之前要判断一次,前面几个数加上新的数字起来有没有新数字大,我们知道只有越加越大的情况下才能出现最大值,所以这里就利用了这一点,如果越...

2021-08-23 21:52:37 47

原创 volatile关键字

可见性第一:使用volatile关键字会强制将修改的值立即写入主存;第二:使用volatile关键字的话,当线程2进行修改时,会导致线程1的工作内存中缓存变量stop的缓存行无效(反映到硬件层的话,就是CPU的L1或者L2缓存中对应的缓存行无效);第三:由于线程1的工作内存中缓存变量stop的缓存行无效,所以线程1再次读取变量stop的值时会去主存读取。那么在线程2修改stop值时(当然这里包括2个操作,修改线程2工作内存中的值,然后将修改后的值写入内存),会使得线程1的工作内存中缓存变量s

2021-08-21 10:16:39 54

原创 锁的升级过程

HotSpot的作者经过研究发现,大多数情况下,锁不仅不存在多线程竞争,而且总是由同 一线程多次获得,为了让线程获得锁的代价更低而引入了偏向锁。当一个线程访问同步块并 获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出 同步块时不需要进行CAS操作来加锁和解锁,只需简单地测试一下对象头的Mark Word里是否 存储着指向当前线程的偏向锁。如果测试成功,表示线程已经获得了锁。如果测试失败,则需 要再测试一下Mark Word中偏向锁的标识是否设置成1(..

2021-08-21 10:06:38 142

原创 java中的对象结构

这一张图就很好的解释了java底层中对象的存储结构,MarkWord用来表示锁的情况,MetaData指向的就是元空间中加载的类的地址,数组长度是数组对象采用的,下面是实例数据对象头HotSpot虚拟机对象的对象头部分包括两类信息:第一类是用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,官方称它为“Mark Word”。第二类类型指针2.2实例数据​ 实例数据部分是对象真正存储的有效信息,即我们在程序代码里面..

2021-08-20 21:55:42 230

原创 synchronized底层分析

首先严格来说synchronized不是真正的锁,他更像是一个加锁的操作,真正的锁是Monitor,它是属于jvm创建的一个c++的对象。首先要看一下monitor的内部结构底层将等待的线程加入到等待队列中,因此来保证原子性的操作,进入synchronized的必须是同一个对象,不加synchronized的对象不会关联Monitor其实在对象头里面存的重量级锁指针指向的就是monitor。JVM基于进入和退出Monitor对 象来实现方法同步和代码块同步,但两者的实现细节不一

2021-08-20 21:32:48 55

原创 .java运行常见的异常

java提供了两种异常机制。一种是运行时异常,一种是检查式异常检查式异常:我们经常遇到的IO异常及sql异常就属于检查式异常。对于这种异常,java编译器要求我们必须对出现的这些异常进行catch 所以 面对这种异常不管我们是否愿意,只能自己去写一堆catch来捕捉这些异常。运行时异常:我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理过NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。throwable err

2021-08-19 22:56:49 107

原创 抽象类和接口的区别

抽象类出现的根本原因:无法完整描述一个事物的类抽象类有一个特征,其抽象方法,必须在子类重写(子类非抽象类),所以,当我们父类的方法,必须要子类重写实现时,用抽象类。如上面的 goToClass() 方法,学生、老师去课堂的目的完全不同,必须自己实现。(1)一个类中有抽象方法,这个类就变成了抽象类。 (2)抽象类中class的前面必须有abstract修饰符。 (3)抽象类中可以有普通方法,也可以有抽象方法,而抽象方法的个数可以是0个,也可以是多个。 (4)子类继承父类,必须重写全部的抽象方法,除非这

2021-08-19 22:43:25 303

原创 封装、继承、多态

面向过程注重过程,就是要分析出解决问题需要的步骤,然后按步骤一步一步实现,类调用时需要实例化,开销比较大,性能比面向对象高面向对象最主要的就是把构成问题的事务分解成各个对象,把对象封装成方法,然后调用方法,优点就是易维护,易扩展,提高了可重用性。 封装就是将一个对象的属性隐藏起来,不允许外界直接访问,但是可以通过调用指定的方法进行访问(name域只能通过,get set方法访问) 继承就是子类继承父类的所有的方法,而且可以拥有自己的方法,提高了代码的重用(对扩展是开放的) 多态

2021-08-19 22:39:19 41

原创 反射的优缺点

Java反射是一种能够在程序运行时动态访问、修改某个类中任意属性(状态)和方法(行为)的机制(包括private实例和方法),java反射机制提供了以下几个功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法。反射的优点:反射提高了程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类反射的缺点1.性能问题使用反射基本上是一种解释操作,用于字

2021-08-19 21:16:36 1956

原创 哈夫曼树分析

给定N个权值作为N个叶子节点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。这是百度搜素给的定义,从严格意义上来说哈夫曼树并不是二叉的而是多叉的,二叉树只是一种形式也是最常见的形式。这一点在百度搜素中也有注明,只是需要做一下调整,构造哈夫曼树的思想是每次选k个权重最小的元素来合成一个新的元素,该元素权重为k个元素权重之和。但是当k大于2时,按照这个步骤做下去可能到最后剩下的元素

2021-08-19 09:57:05 533

原创 填充每个节点的下一个右侧节点指针 II

给定一个二叉树struct Node { int val; Node *left; Node *right; Node *next;}填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。初始状态下,所有next 指针都被设置为 NULL。进阶:你只能使用常量级额外空间。使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。示例:输入:root = [...

2021-08-18 20:43:34 50

原创 省份数量(深度优先算法)

有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。返回矩阵中 省份 的数量。示例 1:输入.

2021-08-17 20:36:19 238

原创 二叉搜索树的后序遍历序列

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。参考以下这颗二叉搜索树: 5 / \ 2 6 / \1 3示例 1:输入: [1,6,3,2,5]输出: false示例 2:输入: [1,3,2,6,5]输出: true来源:力扣(LeetCode)这个是参照Krahets和失火的夏天两位大佬的解题思路我们先来画一个节点多一些的二...

2021-08-17 09:00:14 234

原创 final、finally和finalize

这三个单词长得很像,但是我们知道JavaScript和Java没有任何关系,所以长得像不一定有联系。接下分析一下它们到底都是什么究极有没有联系。final在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)修饰类的时候当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。

2021-08-15 21:45:58 86

原创 盛最多水的容器

给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点(i,ai) 。在坐标内画 n 条垂直线,垂直线 i的两个端点分别为(i,ai) 和 (i, 0) 。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。说明:你不能倾斜容器。示例 1:输入:[1,8,6,2,5,4,8,3,7]输出:49解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为49。来源:力扣(Le...

2021-08-14 21:38:13 72

原创 三数之和等于零

给你一个包含 n 个整数的数组nums,判断nums中是否存在三个元素 a,b,c ,使得a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。示例 1:输入:nums = [-1,0,1,2,-1,-4]输出:[[-1,-1,2],[-1,0,1]]示例 2:输入:nums = []输出:[]示例 3:输入:nums = [0]输出:[]来源:力扣(LeetCode)因为求三个数的和,所以直接多个循环使用...

2021-08-13 22:26:54 1045

原创 浅谈反射、代理和Aop

反射反射机制指的是Java在运行时候有一种自观的能力,能够了解自身的情况为下一步做准备,其想表达的意思就是:在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性(获取方法共三种,Class.forName("类的全限定名")、对象的getClass()方法和类名.class)。获取方法①Class.forName("类的全限定名"),该方法只能获取引用类型的类类型对象。该方法会抛出异常(a.l类加载器在类路径中没有找到该类 b.该类

2021-08-13 22:08:35 375

原创 寻找峰值(二分法)

峰值元素是指其值大于左右相邻值的元素。给你一个输入数组nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。示例 1:输入:nums = [1,2,3,1]输出:2解释:3 是峰值元素,你的函数应该返回其索引 2。示例2:输入:nums = [1,2,1,3,5,6,4]输出:1 或 5解释:你的函数可以返回索引 1,其峰值元素为 2; 或者返回索引 5, 其峰值元素为 6。来源:力扣(LeetCode)因...

2021-08-12 22:01:18 1972 1

原创 寻找旋转排序数组中的最小值

已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。给你一个元素值 互不相同 的数组

2021-08-12 21:42:02 534

原创 java基础(参数传递)

java中的参数传递都为值传递,八大基本类型在方法中传值是直接传值的,无论是在java还是c中都是这样的。而引用类型在传递时会传递过去一个它在堆中的地址。这样的参数传递方式就会导致一些在参数交换产生一些问题,下面这些数值交换方法的使用就会体现出这一点。public class Main { public static void main(String[] args) { SingleInstance instance = SingleInstance.getInstance()

2021-08-11 21:44:50 64

原创 WebScoket和Socket

我记得我最初学校JavaScript的时候我的学长和我说JavaScript和java虽然就差几个字,但是他们没有任何关系,最初是叫liveScript,但是后来又蹭了一波java的热度所以改名叫JavaScript,所以除了名字没有任何关系。webSocke和socket也是如此,首先从二者的使用层面上就不同Socket是传输控制层协议,WebSocket是应用层协议。Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口(不是协议,为了方便使用TCP或UDP而抽象出来..

2021-08-08 15:08:23 465

原创 webSocket简单介绍

首先介绍一下不使用webSocket的聊天室的结构,我们知道http协议是短连接协议,正常在使用中就是数据请求发给后台,后台响应并将数据发送给前台,这是一次交互。而在这种情况下想要实现正常的信息交互就必须要在后台设置监听事件,一直监听着有没有请求有没有发送新的数据,...

2021-08-08 14:38:25 118

原创 webSocket简单应用(五、前端处理)

对于前端而言编写的方法相对比较简单了首先是建立webSocket连接,这一步中会检测浏览器是否支持webSocket,如果支持则将http协议升级为TCP协议并发送连接到服务器。连接路径的格式和后端的连接暴露点格式一致。连接建立后开启webSocket的监听事件。this.webscoket.onopen监听连接事件,后面跟着的是连接建立后调用的方法。同样的道理开启接收关闭和发送的事件的监听,以达到和服务器实时交流的目的,基础的写法就是这样的,这里截取了项目中一部分代码,无论是参数还是后续对数据的处

2021-08-07 10:47:06 316

原创 webSocket简单应用(四、学生查看当前在线课堂)

上一篇中构建了webSocket的基本结构,如何链接如何发送如何关闭。这些功能都只能满足最基本的需求,基本上实现的老师创建房间,学生加入房间并在房间内交流。对于老师端而言通过查找他所教的班级,然后选择要上课的班就可以开设在线课堂了,但是对学生而言必须要知道当前上课老师的房间号才可以进入,而且老师和班级时多对多,学生很难知道到底是那个老师在给他们上课,或者说这个老师有没给他们上课。所以需要这么一个功能,学生能够看到当前他所在班级的在线课堂。首先在WebSocketRoom类中加入静态变量classMess

2021-08-07 09:50:11 163

原创 webSocket简单应用(三、带房间的聊天室编写)

webSocketRoom配置类

2021-08-05 15:49:16 613 1

原创 WebSocket的简单应用(二、房间设置)

上一篇中介绍了webSocket最基本的使用方式和配置类的编写,因为是单层的hashmap,所以可以根据账号进行一对一的放松,但是在群发方面只能够发送给所有人,并不能精确的区分范围。所以这就需要加入房间号这一标识,用来区分群发消息发给谁。只需要在原hashmap上在套一层hashmap记录房间号即可public static Map<String, ConcurrentHashMap<String, Session>> rooms = new ConcurrentHashMap

2021-08-05 10:09:57 592

原创 WeSocket中使用@Autowired无法注入问题

产生原因:spring管理的都是单例(singleton),和 websocket (多对象)相冲突。详细解释:项目启动时初始化,会初始化 websocket (非用户连接的),spring 同时会为其注入 service,该对象的 service 不是 null,被成功注入。但是,由于 spring 默认管理的是单例,所以只会注入一次 service。当客户端与服务器端进行连接时,服务器端又会创建一个新的 websocket 对象,这时问题出现了:spring 管理的都是单例,不会给第二个 webso..

2021-07-31 10:24:14 382

原创 WebSocket的简单应用(一、配置类的编写)

1.WebSocketConfigpackage com.qcby.teach.help.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.server.standard.ServerEndpointExporter;/** *

2021-07-16 15:30:40 615 1

原创 RBAC权限字符串的比较

权限字符串用于校验当前用户访问的路径是否属于他的权限范围。权限字符串的比较本质就是字符串的比较,这里想到了两种解决方法,一种是通过切割成为数组进行比较,另一种是组合成字符串使用kmp算法进行比较。第一种:数组比较因为读取数据库的权限字符串的顺序是固定的,所以每个权限字符串放入数组中存储时就会生成有序数组,这里需要注意一点,因为每个权限对应的访问路径可能有很多个,所以这就要在存储数据时使用符号分割开每个路径,在读取是将它们进行切割在存储。这样就会将长字符串比较简化为一个数组的比较,这种方式在数据读

2021-07-13 22:00:26 1402

原创 RBAC基础理解

RABC简单来说就是角色来进行的权限控制,首先基本的RBAC模型要分为用户、角色和权限,关系如下:因为角色和用户是多对多关系,所以用户和角色通过关联表关联,角色和权限也是多对多的关系,所以角色和权限也用关联表关联。这样就形成了一个基础模型:用户拥有角色,角色拥有权限。整体的运行流程大致分为以下几步,第一步用户登陆账号,后台查询角色情况。第二步用户选择账号角色登陆,后台根据权限列表回显用户的权限并生成菜单。第三步,当用户访问后台方法时,先根据权限字符串对其是否拥有这个权限进行判断,如果有则继续执.

2021-07-13 21:21:49 521

原创 layui下拉框(select)的使用

这是写在前端的html代码,layui会根据majorId对其进行赋值操作,这里有几个点需要注意<select class="majorId" id="nowMajor" lay-filter="major" name="majorId"></select>首先layui并不是直接对select进行操作的,而是根据select里面值的生成一个新的标签,如图而在获取select的值是通过当时渲染数据时的数据名来获取的,如果name是textName就...

2021-07-13 16:46:49 17144 1

原创 打印1-n之间的素数(java筛选法)

import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner x=new Scanner(System.in); int size=x.nextInt(); boolean[] all=new boolean[size]; int number=1; for(int i=1;i<siz.

2021-06-27 17:14:59 777

原创 java中128陷阱

128陷阱简单来说就是使对于大于等于128的数字,用integer存储时,会将它存储到两个对象当中,这是如果使用==private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property

2021-06-14 22:40:07 1216 1

原创 在线学习平台(java)练习项目个人总结(2)

在代码编写中印象最深刻的一次就是代码复制出错,因为我负责的部分中有两处都有基础的增删改查,所以我在写完第一个表的增删改查后将其直接复制作为另一个表的操作的在代码修改时

2021-06-14 09:46:25 260 2

原创 在线学习平台(java)练习项目个人总结(1)

与前几个练习项目最大的不同就是对代码规范书写的要求变高了,尤其是在命名这一部分,无论是HTML还是java文件中全部采用了驼峰命名。在命名修改规范后可以很明显的看到整体的代码结构比之前要清晰...

2021-06-14 08:54:25 1327

原创 ArrayList动态添加基本原理

1.一开始如果是空的构造函数时,会创造一个空的object数组,如果给定了数组的长度则创建给定长度的数组2.在调用第一次Add方式的时候,创建了一个10个长度的Object数组3.在不断的调动add方法会触发grow()方法奔着n+(n>>1)(向右移动一位,基本上就是每次乘以1.5(1.5是综合测试所得,基本上这样的效率比较高))动态添加具体的实现代码:private void grow(int minCapacity) {//传入原数组长度加一int oldCapac

2021-06-01 10:00:58 256

空空如也

空空如也

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

TA关注的人

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