花了20天的时间给粉丝整理的一套"最全"的Java求职笔记(一)

大家好,我是小编LRyab,公众号LRyab博客网,LRyab博客网是分享一些个人成长、思考方向、个人感悟、职业规划,博客涵盖java技术 vue. html. css.前端技术spring全家桶. linux运维技术在365天把你打造出来一个全栈工程师!
点击下方卡片关注公众号,每天分享一篇技术干货!

前言:前几天有粉丝问我,网上java面试题总是参差不齐,希望我为他整理一套全面的java面试题,并且这套java面试题有个要求,必须能够让他20天就能看完这些面试题,他说现在很多面试题我看都得看3个月才能看完,然后我才能去找工作,但是自己得时间有限所以想让我帮他总结一套万能面试java求职笔记。接下来我将会至少分为12个章节进行阐述这套Java求职笔记,感兴趣的可以坚持看完!觉得不错的可以点个赞。

1为什么写这套Java求职笔记

很早的时候我就想写一些Java求职方向的一些文章,由于很长时间耽搁了加上,有粉丝后台问我,可不可以帮他总结一些java求职笔记,他看了很多Java技术有很多技术,很迷茫不知道学哪些,我笑着说,不要着急,无论你到什么时候你都会迷茫,因为技术一直在更新,谢谢你信任我,解救你的迷茫唯一办法就是多看LRyab博客,就是这样我带着粉丝的问题,开始编写了这套Java求职笔记,看完这套求职笔记,我相信很多人都会找到属于自己的心仪工作。

2一套知识大纲技术图

思来想去,本来不想放这套思维大纲技术图,但是很多大佬都喜欢放思维导图,那么我也放一张思维大脑图,方便大家以后学习,在java求职的时候可以带上这张脑图。

3那些年不能忘记的JAVA基础

3.1面向对象(一切皆对象)

  • ✅          面向对象的三大特征是什么?

封装:封装就是把对象的属性和实现细节隐藏起来,仅对外提供公共的访问方法。

将个对象的属性和行为代码封装到一个模块中,也就是一个类中,属性用变量定义,行为用方法定义,方法可以直接访问同一个对象中的属性。

将对象的属性和方法结合一个独立的整体,隐藏其细节,并提供对外访问的接口。

封装优点:1隐藏实现细节

2安全性

3增加代码的复用性:比如在工具类中封装的各种方法,可以任意调用,而不用每处去实现细节。                    4模块化:分模块去封装属性、方法等等。有利于代码调试,相互配合。

继承:多个类中存在相同的属性和行为时,将这些相同的内容抽取到一个单独类中,那么多类无需再定义这些属性和行为,只需要继承这个类即可。继承这个类的为新类,新类称之为原始类的派生类(子类)而原始类称之为新类的基类(父类),派生类可以从它的那里继承方法和实例变量,并且类可以修改或者增加新的方法使之更适合特殊的需求。可通过extends关键字实现继承。

从已知的一个类中派生出来的一个新类叫子类。子类实现了父类所有非私有化的属性和方法,并且根据实际需求扩展出新的行为。

继优点:1、继承是传递的,易于在其基础上构造和扩充。

2、简化对事物的描绘,使得层次更加清晰。

3、减少代码冗余。

4、提高可维护性。

多态:多态性是指允许不同类的对象对同一消息作响应,多态性语言具有灵活、抽象、行为共享,代码共享的优势,很好的解决了应用程序函数同名的问题。

多个不同对象对同一消息作出响应。同一个消息根据不同的对象而采用各种不同的方法。

多态的好处:主要是利于代码扩展。

多态的表现形式:

方法重载和方法重写:方法重载通常指一个类中,相同的方法名对应着不同的方法实现,这些方法名相同的方法其区别在于他们需要的参数不同。

方法重写主要用于父类和子类间,子类重写父类的方法,只是对应的方法实现不同,其方法名和参数都相同。

  • ✅什么是抽象类和接口

抽象类:在java语言中,一个类中的方法只给出类的标准。而没有给出具体实现的方法,这样的类就是抽象类。

接口:在多态机制中接口比抽象类使用起来更加方便。而抽象类组成的集合就是接口。

  • ✅接口和抽象类的区别?

抽象类是为了代码的复用,接口是为了实现多态性。

接口可以进行多实现类似于多继承,抽象类无法实现多继承。

抽象类特征:

抽象类必须有abstract来修饰

抽象类可以不含有抽象方法

如果一个类包含抽象方法,那该类就必须是抽象类。

3.2面试中常见的IO流

IO分为字节流和字符流 字节流和字符流有入输出

字节流分为:inputStream和OutputStream

InputStrean 常用输入流:FileInputStream ByteArrayInputStream

OutputStream 常用输出流:FiLe0utPutStrean  ByteArrayOutputstrean

字符流分为:Reader和Writer

Reader常用入流:BufferReader、InputStreamReader(FileReader)

Writer常用输出点:Bufferaríter·OutputStreaniriter(F1LeWriter) PrintWriter

输入输出流是相对于内存而言的。

  • ✅  文件复制都是通过输入流再到输出流进行一个读写操作?

以文件上传为例?

首先创建一个目标文件路径FiLe

构建一个BufferedOutputStream输出流

获取上传文件的输入流BufferedInputStrean输入流

使用whiLe循环只要输入流的字节长度不为-1,就向输出流内写入字符。

  • ✅java几种常见的几种类型的流?

字节流和字符流· 字节流继承inputstrean和outputstrean,字符流继承InputstreamReader和outputStreamWriter

  • ✅ 谈谈java Io里面常见的类,字节流、接口、实现类

输入流就是从外部文件输入到内存,输出流就是从内存输出到文件

字节流有抽象类inputstream和outputstream他们的子类有,FileoutPutStrean,BufferedoutPutstrean等字符流有BufferReader和Writer。

它们都实现了CLoseabLe,FLushabLe、Appendeble这些接口·程序中输入输出全是以流的形式保存。流中实际保存的实际上全是字节文件。

  • ✅  IO流中的阻塞

Java中阻塞方法是指程序调用改方法时,必须等待输入数据可用或者检测到输入结束或者抛出异常,否则程序会一直停留在改语句上,不会执下面的语句比如read()和readL.ine()方法

  • ✅  字节流与字符流有什么区别?

计算机中的一切都是二进制的字节形式存在,底层设备永远只按受字节数据,有时候写字符到底层设备,需要将人眼看的懂得字符转换为字节再进行写入字符流时,字节流得包装,字符流则是直接接收字符串,它内部将传转化为字节,再写入属出设备。

  • ✅讲讲NIO

传统IO流是阻塞式的,会一直监听一个ServerScoket,再调用reader方法时,他会一直等待缓存区满才返回。

NIO是非阻塞式核心类:

Buffer为所有原始类型提供Buffer缓存支持

Charset字符集编码解码解决方案

Channel一个新的原始I/0抽象,用于读写Buffer类型。

  • ✅Java IO总结

数据需要读取使用InputStream、Reader

数据需要写入使用OutPutStream,Writer

操作数据如果是纯文本:使用Reader和Writer

不是则使用Inputstreem和outputstream

操作案例:递归读取文件夹下的文件

文件的上传下载(看我其他博文)

3.3你应该知道的多线程

线程和进程:

当一个程序被运行,就开启了一个进程, 比如启动了qq,word

程序由指令和数据组成,指令要运行,数据要加载,指令被cpu加载运行,数据被加载到内存,指令运行时可由cpu调度硬盘、网络等设备。

线程:一个进程内可分为多个线程

一个线程就是一个指令流,cpu调度的最小单位,由cpu一条一条执行指令

并行和并发

并发:单核cpu运行多线程时,时间片进行很快的切换。线程轮流执行cpu

并行:多核cpu运行 多线程时,真正的在同一时刻运行

为什么要用多线程?

多线程能实现的都可以用单线程来完成,那单线程运行的好好的,为什么java要引入多线程的概念呢?

多线程的好处:

程序运行的更快!快!快!

充分利用cpu资源,目前几乎没有线上的cpu是单核的,发挥多核cpu强大的能力

多线程难在哪里?

单线程只有一条执行线,过程容易理解,可以在大脑中清晰的勾勒出代码的执行流程

多线程却是多条线,而且一般多条线之间有交互,多条线之间需要通信,一般难点有以下几点

多线程的执行结果不确定,受到cpu调度的影响

多线程的安全问题

线程资源宝贵,依赖线程池操作线程,线程池的参数设置问题

多线程执行是动态的,同时的,难以追踪过程

多线程的底层是操作系统层面的,源码难度大

Java多线程的基本使用:定义任务,创建和运行线程

定义任务

继承Thread类 (可以说是 将任务和线程合并在一起)

实现Runnable接口 (可以说是 将任务和线程分开了)

实现Callable接口 (利用FutureTask执行任务)

Thread实现任务的局限性

任务逻辑写在Thread类的run方法中,有单继承的局限性

创建多线程时,每个任务有成员变量时不共享,必须加static才能做到共享

Runnable和Callable解决了Thread的局限性

但是Runbale相比Callable有以下的局限性

任务没有返回值

任务无法抛异常给调用方

创建线程的方式

通过Thread类直接创建线程

利用线程池内部创建线程

启动线程的方式

调用线程的start()方法

守护线程:

默认情况下,java进程需要等待所有线程都运行结束,才会结束,有一种特殊线程叫守护线程,当所有的非守护线程都结束后,即使它没有执行完,也会强制结束。默认的线程都是非守护线程。垃圾回收线程就是典型的守护线程。

线程阻塞:

线程的阻塞可以分为好多种。

BIO阻塞,即使用了阻塞式的io流

sleep让线程休眠进入阻塞状态

a.join() 调用该方法的线程进入阻塞

同步锁阻塞

同步锁等待产生阻塞

sleep()

使线程休眠,会将运行中的线程进入阻塞状态。当休眠时间结束后,重新争抢cpu的时间片继续运行

join()

join是指调用该方法的线程进入阻塞状态,等待某线程执行完成后恢复运行

interrupt()

中断线程

线程分为哪几种状态?

初始状态、可运行状态、运行状态、阻塞状态、终止状态。

Thread类中的核心方法?

Object类中与线程有关的方法?

wait() notify()方法 随机唤醒被wait的一个线程。

notifyAll()

native 装饰的方法为本地方法,调用非java语言编写的ddl接口。称之为本地方法。

线程安全:

多线程调用同一个对象的临界区的方法时,对象的属性值一定不会发生错误,这就是保证了线程安全。

synchronized

同步锁也叫对象锁,是锁在对象上的,不同的对象就是不同的锁,保证线程安全的,是阻塞式的解决方案。

当一个线程执行完synchronized的代码块后 会唤醒正在等待的线程

加锁是加在对象上,一定要保证是同一对象,加锁才能生效

线程通信:

线程间通信可以通过共享变量+wait()&notify()来实现

wait()将线程进入阻塞状态,notify()将线程唤醒

wait()和sleep()的区别

二者都会让线程进入阻塞状态,有以下区别

wait是Object的方法 sleep是Thread的方法

wait会立即释放锁 sleep不会释放锁

wait后线程的状态是Watting sleep后线程的状态为 Time_Waiting

生产者消费者模型案例

生产者来生产数据,消费者来消费数据,生产者生产满了就不生产了,通知消费者取,等消费了再进行生产。

同步锁生活银行取钱案例

死锁:死锁会导致程序无法运行下去

线程池:

java开发中经常有池子的思想,如数据库连接池、Redis连接池。

线程池的好处:降低资源消耗,通过池化思想,减少创建线程和销毁线程的消耗,控制资源

提高响应速度,任务到达时,无需创建线程即可运行

提供更多更强大的功能,可扩展性高

3.4常见的底层性能调优方案

  • ✅你怎样给tomcat调优

  • ✅如何加大comcat连接数

  • ✅怎样加大tomcat的内存

  • ✅tomcat中如何禁止列目录下的文件

  • ✅Tomcat有几种部署方式

  • ✅Tomcat的优化经验

  • ✅描述一下JVM 加载CIass文件的原理机制?

  • ✅GC 是什么? 为什么要有 GC?

  • ✅简述 Java 垃圾回收机制。

  • ✅如何判断一个对象是否存活?(或者 GC 对象的判定方法)

  • ✅垃圾回收的优点和原理。

  • ✅有什么办法主动通知虚拟机进行垃圾回收?

  • ✅Java 中会存在内存泄漏吗, 请简单描述。

  • ✅java深拷贝和浅拷贝。

  • ✅什么是类加载器, 类加载器有哪些?

  • ✅类加载器双亲委派模型机制?

  • ✅Mysql数据库常见性能优化

3.5常见设计模式案例

java设计模式:

顾名思义java中一些代码被固定写法形成了一种模式给这个模式起了个名字。所以叫设计模式

java中的设计模式分为23种,但是你至少会这三种并且能举例说明哪些地方用到了。

(1)单例模式、代理模式、工厂模式、观察者模式、装饰者模式、适配器模式

单例模式又分为:懒汉式和饿汉式  单例保证一个对象在JVM种只能有一个实例

struts2是多例的每次属性渲染都得重新生成新得对象。

spring bean id是唯一生成得所以是单例得

常用:获取数据库得conn链接可以使用单例设计模式。

(2)代理模式

静态代理和动态代理

jdk自带得动态代理和cglib,javaaassist(字节码操作库)

动态代理是基于反射原理。需要使用反射机制实现匿名代理类

spring Aop切面就是使用CGLIB动态代理,实现日志切面。asm、cglib jar包

spring 会自动在jdk动态代理和CGLIB之间切换

(3)工厂模式

工厂模式创建对象大大增加了创建对象封装得层次

mybaties中的事务模块和数据源模块都使用了工厂模式

(4)观察者模式

定义了对象之间的一对多,这样一来,一个对象的改变所有的依赖对象都会接收到通知并且自动更新。

(5)装饰者模式和适配器模式

java IO到处都是装饰者模式:bufferReader和BufferedWriter增强了Reader和Writer对象,增强了单个对象的能力。

3.6java中你不知道的容器集合技术

  • ✅什么是集合?

集合就是一个放数据的容器,准确的说是放数据对象引用的容器

集合类存放的都是对象的引用,而不是对象的本身

集合类型主要有3种:set(集)、list(列表)和map(映射)。

  • ✅集合的特点

集合用于存储对象的容器,对象是用来封装数据,对象多了也需要存储集中式管理。

和数组对比对象的大小不确定。因为集合是可变长度的。数组需要提前定义大小

  • ✅集合和数组的区别

数组是固定长度的;集合可变长度的。

数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。

数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同数据类型。

  • ✅常见的集合类有哪些?

Collection接口的子接口包括:Set接口和List接口

Map接口的实现类主要有:HashMap、TreeMap、 Hashtable、ConcurrentHashMap以及Properties等

Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等

List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等

  • ✅List、Set、Map三者的区别?

Collection集合的子接口有Set、List、Queue三种子接口。

List:一个有序的容器,元素可以重复,可以插入多个null元素,元素都有索引。ArrayList、LinkedList。

Set:一个无序,不可以存储重复元素,只允许存入一个null元素,必须保证元素唯一性。

  • ✅集合框架的底层数据结构

List子类:ArrayList Object数组  LinkedList双向循环链表

Set子类:HashSet 基于HashMap实现的  TreeSet红黑树 自平衡的排序二叉树

Map子类:HashMap数组+链表 解决哈希冲突。LinkedHashMap 数组、链表或者红黑树

HashTable 数组和链表组成的。treeMap红黑树。

  • ✅哪些集合类的线程是安全的

Vector、hashTable、ConcurrentHashMap因为内部含有synchronized所以线程安全。

  • ✅java集合的快速失败机制

假设2个线程,线程1通过Iterator在遍历A集合的元素,在某一个时刻,线程2修改了集合A的结构,那么这个时候就会抛出:ConcurrentModifyicationException异常从而产生fail-fast机制。

  • ✅怎么确保一个集合不被修改

可以使用 Collections. unmodifiableCollection(Collection c) 方法来创建一个只读集合,这样改变集合的任何   操作都会抛出 Java. lang. UnsupportedOperationException 异常。、

  • ✅迭代器 Iterator 是什么?

Iterator 接口提供遍历任何 Collection 的接口。我们可以从一个 Collection 中使用迭代器方法来获取迭代器实例,迭代器允许调用者在迭代过程中移除元素。

  • ✅Iterator 怎么使用?有什么特点?

List<String> list = new ArrayList<>();
Iterator<String> it = list. iterator();
while(it. hasNext()){
String obj = it. next();
System. out. println(obj);
}

Iterator 的特点是只能单向遍历,但是更加安全,因为它可以确保,在当前遍历的集合元素被更改
的时候,就会抛出 ConcurrentModificationException 异常。

  • ✅如何一边遍历一边移除Collection中的元素呢?

一边遍历一边修改 Collection 的唯一正确方式是使用 Iterator.remove() 方法,Java 一般不允许一个线程在遍历 Collection 时另一个线程修改它。

  • ✅遍历一个 List 有哪些不同的方式?每种方法的实现原理是什么?Java 中 List遍历的最佳实践是什么?

遍历方式有以下几种  for循环遍历、迭代器遍历、foreach循环遍历

最佳实践:ArrayList使用for循环遍历

  • ✅说一下ArrayList的优缺点

ArrayList 底层以数组实现,是一种随机访问模式。

ArrayList 在顺序添加一个元素的时候非常方便。

ArrayList 比较适合顺序添加、随机访问的场景。

  • ✅如何实现数组和List之间的转换

数组转 List:使用 Arrays. asList(array) 进行转换。

List 转数组:使用 List 自带的 toArray() 方法。

  • ✅ArrayList和LinkedList的区别是什么?

数据结构:一个数组,一个双向链表

随机访问:ArrayList比LinkedList在随机访问的时候效率高,增加删除元素效率linkedlist链表效率要高于数组

内存占用:Linkedlist比arrayList要占用内存

2者都不能保证线程安全

  • ✅  ArrayList和vector的区别是什么?

vector线程安全一些

性能:ArrayList在性能方便优于Vector

扩容:ArrayList每次扩容只会增加50%,而Vector每次会增加1倍

  • ✅  多线程下如何使用ArrayList?

ArrayList 不是线程安全的,如果遇到多线程场景,可以通过 Collections 的 synchronizedList 方法将其转换成线程安全的容器后再使用。

  • ✅ 为什么ArrayList的elementData加上transient修饰?

transient关键词修饰的变量不参与序列化,每次之序列化ArrayList中的非transient元素,然后遍历Element打他,只序列化已存入的元素,这样既加快了序列化的速度,又减少了序列化之后的文件大小。

  • ✅List和Set的区别

List支持for循环,也就是通过下标来遍历,也可以使用迭代器,但是set只能用迭代,因为它是无序,无法用下标来取得想要的值。

  • ✅简单说一下HashSet 的实现原理

HashSet 是基于 HashMap 实现的,HashSet的值存放于HashMap的key上,HashMap的value统一为present,因此 HashSet 的实现比较简单,基本上都是直接调用底层HashMap 的相关方法来完成,HashSet 不允许重复的值。

  • ✅HashSet与HashMap的区别

  • ✅说一下链表数据结构

链表是可以将物理地址上不连续的数据连接起来,通过指针来对物理地址进行操作,实现增删改查等功能。

链表大致分为单链表和双向链表。

单链表:每个节点包含两部分,一部分存放数据变量的data,另一部分是指向下一节点的next指针

双向链表:除了包含单链表的部分,还增加的pre前一个节点的指针

链表的优点

插入删除速度快、内存利用率高,不会浪费内存(可以使用内存中细小的不连续空间),大小没有固定,拓展很灵活。

链表的缺点

不能随机查找,必须从第一个开始遍历,查找效率低

  • ✅说一下HashMap的实现原理?

HashMap的数据结构:在java编程语言中,最基本的结构就2种,一个数组,另外一个是模拟指针(引用),所有的数据结构都可以使用者2个基本结构构造的。

HashMap实际上是一个链表散列的数据结构,即数组和链表的结合体。

HashMap是基于Hash算法实现的

放值和取值:过程,Hash冲突,将冲突的放入链表做进一步的比较,拉链法解决了hash冲突。

  • ✅  HashMap1.8之后发生了哪些变化?

resize扩容优化

引了红黑树链表过长影响查询效率

多线程数据丢失问题

  • ✅红黑树

平衡二叉树(一种特殊的二叉树)

红黑树添加和删除,最常用到旋转和变色,因为可以使这棵树重新变成红黑树

  • ✅HashMap的put方法的具体流程?

  • ✅HashMap扩容操作怎么实现的?

  • ✅HashMap是怎么解决哈希冲突的?

当两个不同的输入值,根据同一散列函数计算出相同的散列值的现象,我们就把它叫做碰撞(哈希碰撞)。

我们将数组和链表结合在一起,发挥两者各自的优势,就可以使用俩种方式:链地址法和开放地址法可以解决哈希冲突。

  • ✅能否使用任何类作为Map的key?

  • ✅为什么HashMap中的String、Integer这样的包装类更适合为key?

能够有效的减少Hash碰撞的几率

  • ✅HashMap和HashTable的区别?

HashTable已经淘汰

  • ✅TreeMap介绍?

TreeMap是有序的基于红黑树实现

  • ✅如何决定使用HashMap还是TreeMap

TreeMap适合遍历,HashMap适合集合元素添加和删除

  • ✅HashMap 和 ConcurrentHashMap 的区别

最大的区别是线程安全

  • ✅ConcurrentHashMap 和 Hashtable 的区别?

HashTable全表锁,ConcurrentHashMap分段锁,效率高

  • ✅说一说ConcurrentHashMap底层的具体实现以及实现原理

  • ✅comparable 和 comparator的区别?

4结束语

混社会这么久,越来越觉得思考的重要性,没有思考就没有成就,现在社会内卷严重,大多数人都知道去努力,但是大多数的人没有养成思考的习惯,如果你学会思考,你整个人就会很爽,就好比你在沙漠里面找到了一瓶水,现在社会谎言、潜规则、利益太多,如果你不思考,只能跟着别人的思想走。

5个人说明

(0)

相关推荐