先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
正文
1.总线锁定
2.缓存一致性协议
三大特性:原子性,可见性,有序性
六**.JVM****的锁优化**
1.自旋锁和自适应自旋锁
线程挂起和恢复都需要很大的性能开销,很多共享数据的锁定状态只持续很短的时间,为这段时间挂起恢复不值得,所以可以让现场进入一个自旋状态,但仍占用cpu的时间,默认是10次,超过10次则采用传统的方式挂起线程。自适应自旋锁会根据上次在这个锁上自旋的时间调整自选次数
2.锁消除
检测到对局部变量加锁,会自动将锁消除,如在一个方法里面有sb = s1 + s2 + s3以前会转化为StringBuffer(线程安全,有加锁)的append操作,优化之后会转换成StringBuilder的sppend操作
3.锁粗化
对一个对象反复加锁解锁,如上述的append方法,编译器会优化,只在最外层加一个锁
4.轻量级锁
对象有一个对象头,对象头分两部分区域,一部分存储子树的hashcode,GC分代年龄,锁标志位等,官方成为mark word,另一部分用于存储指向方法区对象类型的指针;
轻量级锁的执行过程是代码进入同步块的时候,如果当前对象没有被锁定(锁标志为是01)则先在线程的栈帧中建立一个锁记录空间(lock record)将对象的mark word拷贝过来,然后利用cas操作尝试将对象的markword更新为指向lock record,如果成功则当前线程拥有该对象锁,并且将锁标志位从01改为00,如果更新失败则会检查当前对象markword是否指向当前线程的栈帧,如果是则直接进入同步块执行否则说明当前的对象锁已经被其他线程占有。如果有两条以上的线程竞争这个锁,那就会膨胀成重量级锁,锁标志为变成10;
5.偏向锁
锁对象第一次被线程获取的时候,会将当前的锁标志设置为偏向锁01状态,并使用cas操作将当前线程的id记录在markword当中,如果成功那么在以后的操作当中不需进行任何操作就可以进入同步代码块,当有另外一个线程获取当前锁的时候,偏向模式就宣告结束,撤销偏向锁之后恢复到未锁定或者轻量级锁状态
JAVA****基础
==============
String
1.string s1 = “aaa” 与 String s1 = new String(aaa);
前者会在Stringpool中创建一个对象,如果Stringpool中已经有了,则直接引用
后者会在Stringpool和堆中分别创建一个对象,如果StringPool中已经有了则只创建一个对象
2.调用s1.integer()方法,可以将字符串放入StringPool中,如果已经存在则直接返回这个对象
继承
**1.**几种修饰符的访问权限范围
2. == equals hashcode****的关系
1.==是比较两个对象的地址是否相等
2.equals默认和 == 一样也是比较地址,也可以根据自己的需求来重写什么叫做相等
3.hashcode 是根据对象的地址来返回一串int型数字,如果对象不一样的话返回的值也不一样
3.为什么重写equals的同时也要重写hashcode
首先必须满足如果equals相同,那么hashcode也必须相同,如果hashcode不相同,那么equals必须不相同的原则,否则会导致该类无法与基于散列值的集合类(hashmap , hashset ,hashtable)结合正常运行
因为对于这些集合在进行重复性判断时,是先用hashcode判断,如果相同在用equals判断
4.hash****冲突的解决方法
1.开放地址法(线性探测法,二次探测法)
2.在散列函数法
3.链地址法
5.hashtable与hashmap的区别
1.hashmap线程不安全,hashtable线程安全
2.hashmap最多允许一个键为null,而hashtable不允许
3.hashtable中默认的hash数组大小为11,增加的方式是old*2+1,而hashmap默认是16,肯定是2的指数
4.计算hash的方法不一样,hashtable是直接用hashcode,而hashmap使用了key的高16位和低16位做异或运算
Linkedhashmap继承于hashmap,可以按顺序读取,底层使用的是双向链表
TreeMap实现了sortmap接口,可以对元素进行排序,底层使用的红黑树
7.java BIO NIO AIO 序列化
字节操作:使用inputStream和outPutSream实现,字节是传输和存储的最小单位
字符操作:inputStreamReader:将字节流解码成字符流
OutPutStramWriter:将字符流编码成字节流
对象操作:序列化就是将对象转换成字节序列,方便存储和运输,两个用途:
1.把对象的字节序列永久地保存到硬盘中,通常存放在一个文件里
2.在网络上传送对象的字节序列
在很多应用中,需要对某些对象进行序列化,让他们离开内存空间,入住到物理磁盘方便长期保存,比如session对象,当有大量用户并发访问的时候可能会出现10万个session对象,内存吃不消,此时就需要将这些session先序列化到硬盘中,等要用的时候在把对象还原到内存中。
当两个进程在进行远程通信的时候,彼此可以发送各种类型的数据,无论是何种类型的数据,都会以二进制的序列在网络上传送。发送方需要把这个java对象转换成字节序列,才能在网络上传送;接收方则需要把字节序列恢复成java对象。
Io与NIO的区别:
1.NIO是非阻塞的
2.NIO是面向缓冲区的,IO是面向流的
AIO:异步非阻塞
8.static关键字的作用
一.修饰变量:
1.静态变量在类加载的时候被创建并初始化,只被创建一次(类加载只进行一次),可以修改
2.静态变量属于整个类而不属于某个对象。
二.修饰方法
1.可以通过类名来访问,不需要创建对象来访问,可以用来实现单例模式
2.静态方法只能调用静态方法和静态变量
三.修饰静态代码块
在类加载的时候执行,且只执行一次
9.单例模式
实现:
1.为什么要用判断双重:
因为可能有两个线程都执行完了第一个if语句,如果没有第二重判断,那么当其中有个线程执行完synchronized里面的语句之后,另外一个线程跟着也会执行,这样就达不到单例模式的效果
2.第一重判断去掉也可以实现,为什么不去掉
这个设计性能问题,因为
参考:https://qinjiangbo.com/mechanism-of-double-locking-check.html
10.this与super关键字
9.java中的多态
分为两种:
1.编译时多态:体现在重载(方法名相同而参数不同),在编译时期就根据传入的参数确定好调用哪个方法;
2.运行时多态:体现在方法的重写。在运行时期判断引用类型的实际类型根据实际的类型调用其相应的方法;
当父类对象引用变量引用子类对象时,被引用对象的类型决定了调用谁的成员方法,引用变量类型决定可调用的方法。如果子类中没有覆盖该方法,那么会去父类中寻找。
参考链接:https://www.runoob.com/w3cnote/java-polymorphism.html
10.接口类和抽象类的异同
区别:
1.抽象类可以有非抽象方法,但接口只能有抽象方法
2.接口中的成员变量默认修饰为public static final(高度抽象的模版,所以这些都是提取出来的不变特征),方法默认修饰为public abstract。抽象类中的成员变量可以被不同的修饰符来修饰
3.类可以实现多个接口但只能继承一个抽象类
相同:
1.不能被实例化
2.派生类都必须实现未实现的方法
11.instanceof
用来判断一个对象是否是一个类的实例
12.各种排序算法复杂度及稳定性
1.java底层如何实现排序的
Java中Arrays.sort使用了两种排序方法,快速排序和优化归并排序。
快速排序主要针对基本的数据类型(int short long)排序,而归并排序用于对象类型的排序
如果数据量小于60会使用插入排序,插入排序是稳定的
13.java中的堆和栈
栈:主要用于存储局部变量和对象的引用变量,每个线程都有一个独立的栈空间,所以线程之间是不共享数据的;
栈的特点是存取速度快,但所存数据的大小和生存期必须是确定的(编译后就已经确定大小)
堆:堆中主要存储实例化的对象和数组。线程共享。堆的优势是可以动态的分配内存大小,生存期也不必事先告诉编译器,但缺点是存取速度较慢
Linux基本面试题:
Ls:用于显示指定工作目录下的类容,不会列出详细信息
Ll:会列出当前文件目录的详细信息,含有时间,权限,大小等
Cd:用于切换到目标目录
Mkdir:用于简历当前目录的子目录
rm-r 删除的文件或者目录,需确认
rm –rf同上但无需确认
cp:复制文件 若复制目录则必须加上-r
数据库****MySQL
================
一**.**索引
1.B树,B+树,以及两者的区别
B树是一种多路平衡查找树,其每一个节点都存储Key和data
B+树是B树的一个变种,叶子节点存储data,非叶子节点只存储key,B+树的叶子节点增加了顺序访问指针,每一个叶子节点都可以访问到他的下一个叶子节点
区别:
1.B+树种只有叶子节点会带有全部信息,非叶子节点只起到索引的作用,二B树的所有节点都带有全部信息,B+树的每一层节点都会再次出现在下一层节点上
2.B+树种所有叶子节点都是通过指针连在一起,B树则没有
2.索引的优点和缺点
优点:可以加大检索速度
缺点:创建和维护索引需要耗费时间
3.Mysql为什么选择B+树
Mysql数据本质上是放在外部存储的,B+树是为了加快读取速度二设计的一种数据结构
1.可以减少i/o次数,只有叶子节点才存储数据,非叶子节点存储索引,这样一次读取到内存的关键字增多,相对i/o次数也就减少(根据区别一)
2.能够提供稳定高效的范围扫描,因为所有的叶子节点都互相连接(根据区别二)
4.索引越多越好吗?
索引可以提高select的效率,但是也降低了insert和updata的效率,因为插入和更新的时候可能会重建索引,索引怎么建索引要慎重考虑。
5.索引分类
1.B+树索引:以b+树作为数据结构的索引
2.hash索引:能以O(1)的时间复杂度查找,但失去了有序性,innodb有一个自适应哈希索引,当这个索引值被频繁使用时会在b+树上创建一个哈希索引
3.全文索引:用于查找文本的关键词,中文需要由中文分词插件
二**. MySQL****优化**
一.MySQL的优化,主要分为索引的的优化,sql语句的优化,表的优化。同时可以使用缓存增加效率
1.索引的优化
只要列中含有null,最好不要再此列设置索引
对于经常在where语句中使用的列,最好设置一个索引
对于like语句,以%或者-开头的不会使用索引,以%结尾会使用索引
二.sql语句的优化
查询优化要尽量避免全表扫描
查询时能不用*就不用*,尽量写字段名
三**. MySQL****常问问题**
1.数据库如何应对大规模的写入和读取
(1)使用NoSQL,通过降低数据的安全性,减少对事物的支持,减少复杂查询的支持来获取性能的提升;但有些场合NoSQL无法满足要求
(2)分库分表:
水平切分:不修改数据库的表结构,通过对表中的数据拆分而达到分片的目的,一般水平切分在查询的时候可能会用到union操作(多个结果并)
可以根据hash或者日期来进行分表
垂直切分:修改表结构,按照访问的差异将某些列拆分出去,一般查询数据的时候可能会用到join操作;把常用的字段放在一个表中,不常用的放在一个表中;把字段比较大的比如text字段拆出来放在一个表中。
分库:分表能够解决数据量过大带来的查询效率下降问题,但是却无法给数据库的并发处理能力带来质的提升;分库可以对关键字取模的方式来对数据访问进行路由;
(3)读写分离:
读写分离是在主服务器上修改数据,数据也会同步到从服务器上,从服务器只能提供读取,不能写入,实现备份的同时也实现了数据库的性能优化
如何保证数据一致性:
(1)主节点
保证事务每次提交之后,要确保binlog都能刷新到磁盘中,只要有了binlog,innoDB就有方法恢复数据,不至于导致主从复制的数据丢失
(2)从节点
开启 relay log 自动修复机制,发生 crash 时,会自动判断哪些 relay log 需要重新从master 上抓取回来再次应用,以此避免部分数据丢失的可能性。
2.数据库事务及其隔离级别
事务的特性:ACID
事务在并发的时候,隔离性很难保证主要可能出现下面这些问题:
脏读:一个事务读了另外一个事务未提交的数据,如果另一个事务回滚则会发生脏读
不可重复读:一个事务前后读取同一行数据,如果在这个过程中有其他事务修改了此数据则会发生不可重复读
幻读:一个事务前后读取范围的时候
事务隔离级别:
MySQL实现事务是基于undo/redo日志实现的:
undo日志记录修改前的状态,ROLLBACK基于UNDO日志实现;
REDO日志记录修改后的状态,事务的持久性基于REDO日志实现
两种解决脏读、不可重复读、幻读的方案:
MVCC(性能较高,但读的可能是历史版本)
1.版本链:对于每一行的数据,在undo日志中,总会记录每个版本记录以及对应的事务id,
2.readView:
核心问题:当前版本链中哪个版本对当前事务可见
Readview包含的内容:{当前活跃的事务id,下一个应该分配的事务id,当前自己的事务id},根据当前读的版本事务id和这个readview对比,如果是活跃的或者大于下一个应该分配的事务id则说明当前版本对此事务不可见,应该前读一个版本,依次类推直到找到可见的版本
提交读:每次读取数据前都会生成一个readview
可重复读:在第一次读取时句时生成一个readview
锁(性能不高,但读的是最新版本):
MyISAM和innoDB的区别
1.innodb支持行锁,myisam不支持行锁
2.innodb支持事务,myisam不支持事务
3.innodb支持回滚和安全回复,myisam不支持
4.innodb的索引就是数据,myisam的索引只存储了主键和行号,还需要根据行号去查找相应的记录
5.innodb更适合写密集的表,myisam更适合读密集的表
计算机网络
=========
1.tcp和udp的区别:
Udp:无连接,尽最大可能交付,没有拥塞控制流量控制
Tcp:面向连接,可靠交付,有拥塞控制和流量控制
2.输入一条url,整个过程:
1.DNS解析,获取ip地址(本机,本地域名服务器,根域名服务器,顶级域名服务器,权限域名服务器)
2.建立TCP连接
3.浏览器发出http请求
4.服务器进行响应
5.TCP连接释放
6.浏览器渲染
3.为什么是三次握手,四次挥手
三次握手:防止之前滞留的连接请求再次到达服务端
四次挥手:因为tcp是全双工模式,客户端停止发送请求之后,服务端也要停止发送请求
4.time_wait存在的原因,时间是多少(两倍的报文最大存活时间)
1.确保客户端发送的最后一个报文能被收到,服务端可以正常关闭。
2.让所有报文都在网络中消失,时间是两倍的最大报文存活时间。
5.tcp的可靠传输靠什么:
超时重传:如果已经发送的报文在超过时间内没有被确认,那么就重新发送这个报文
6.Tcp的滑动窗口
发送方和接收方都有一个滑动窗口
7.TCP流量控制
流量控制是为了控制发送方的发送速率,保证接收方来得及接收
总结
无论是哪家公司,都很重视高并发高可用的技术,重视基础,重视JVM。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,是不是能真的得到锻炼。其实我写了这么多,只是我自己的总结,并不一定适用于所有人,相信经过一些面试,大家都会有这些感触。
最后我整理了一些面试真题资料,技术知识点剖析教程,还有和广大同仁一起交流学习共同进步,还有一些职业经验的分享。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
四次挥手:因为tcp是全双工模式,客户端停止发送请求之后,服务端也要停止发送请求
4.time_wait存在的原因,时间是多少(两倍的报文最大存活时间)
1.确保客户端发送的最后一个报文能被收到,服务端可以正常关闭。
2.让所有报文都在网络中消失,时间是两倍的最大报文存活时间。
5.tcp的可靠传输靠什么:
超时重传:如果已经发送的报文在超过时间内没有被确认,那么就重新发送这个报文
6.Tcp的滑动窗口
发送方和接收方都有一个滑动窗口
7.TCP流量控制
流量控制是为了控制发送方的发送速率,保证接收方来得及接收
总结
无论是哪家公司,都很重视高并发高可用的技术,重视基础,重视JVM。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,是不是能真的得到锻炼。其实我写了这么多,只是我自己的总结,并不一定适用于所有人,相信经过一些面试,大家都会有这些感触。
最后我整理了一些面试真题资料,技术知识点剖析教程,还有和广大同仁一起交流学习共同进步,还有一些职业经验的分享。
[外链图片转存中…(img-Da17uuNE-1713704619557)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-quG0oN5m-1713704619557)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!