欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java初级必备面试知识

程序员文章站 2022-03-13 21:24:31
来自一名毕业半年的程序媛关于初级程序员面试所必备技能的总结,请大家多多指教。JVM(虚拟机)1、JAVA运行时的内存划分程序计数器:用来记录当前线程所执行的字节码的行号,以便于获取下一条所要执行的字节码;当多线程运行时,每个线程的切换需要知道线程上一次所执行的状态、位置。因此程序计数器是线程是有的。虚拟机栈:由一个一个栈帧组成的,栈帧是在方法调用时产生的,栈帧是由局部变量区、操作数栈等组成的。每创建一个栈帧压栈,在方法执行完成之后出栈。会有两种异常的出现:1:*err...

来自一名毕业半年的程序媛关于初级程序员面试所必备技能的总结,请大家多多指教。

JVM(虚拟机)

1、JAVA运行时的内存划分

程序计数器:

用来记录当前线程所执行的字节码的行号,以便于获取下一条所要执行的字节码;当多线程运行时,每个线程的切换需要知道线程上一次所执行的状态、位置。因此程序计数器是线程是有的。

虚拟机栈:

由一个一个栈帧组成的,栈帧是在方法调用时产生的,栈帧是由局部变量区、操作数栈等组成的。每创建一个栈帧压栈,在方法执行完成之后出栈。
会有两种异常的出现:
1:*error,出现死循环时,会造成栈帧过多。线程执行过程中栈帧大小超出虚拟机栈限制。
2:OutOfMemoryerror:若虚拟机允许动态扩容,但尝试时内存不足,或者创建新线程时,申请不到足够的内存。

Java堆:

虚拟机内最大的内存分配区域,所有的对象都是在这里进行内存分配。java堆也是垃圾回收器重点管理的区域。

方法区:

存放已经被加载的类信息(永久代)。

元数据区:

在jdk1.8之后,取代方法区,会根据使用情况动态调整,但是不能无限。

运行时常量池:

存放一些符号引用,当new一个对象时,会检查是否有这个对象的引用。

直接内存(堆外内存):

不是由虚拟机管理,由操作系统管理,通过堆内存的directbytebuffer对象操作的堆外内存,由老年代的fullGc或者system.gc()回收。
2、类的生命周期
加载——验证——准备——解析——初始化——使用——卸载
类的加载:将.class文件中的二进制读入到内存中,将其放入运行时数据区的方法区内,然后在堆区创建一个.java.lang.class对象,用来封装在方法区的数据结构,类的加载最终是在方法区的class对象,class对象封装了在方法区的数据结构。
验证:元数据、文件格式、符号引用、字节码的验证。
准备:对静态变量分配内存,并初始化默认值。
解析:将类中的符号转换为直接引用。
初始化:对静态变量,静态代码块执行初始化操作。、
双亲委派模型:当收到类加载的信息时,子类加载器不会立即加载,会先传到父类加载器加载,依次向上,所以所有的类加载请求都会上传到*启动类加载器中,只有当父类加载器找不到类信息,才会交给子类加载器加载。
3、内存结构:三大块(方法区、堆内存、栈)
堆内存分为新生代和老年代;新生代又分为Eden区、fromsurvivor、tosurvivor(内存比例为8:1:1)当Eden内存不足时,会发生minorGc(E——S)
4、垃圾回收
对象是否存活?
引用计数法:每个对象都有引用计数属性,当增加加一,释放减一,当计数为0时,对象被回收。
可达性分析:通过GcRoot对象向下搜索,整个搜索路径就称为引用链。当一个对象到GcRoot没有引用链时,就可回收。
可以当做GcRoot对象的有:虚拟机栈中引用的对象,方法区中常量引用的对象,方法区中类静态性实体引用的对象。
垃圾收集算法:
标记清除法:把不需要被回收的对象进行标记,对需要回收的对象进行回收。缺点:太多碎片化,没有可连续引用的空间。
标记整理法:把不需要被回收的对象标记放到片区域,将这片区域之外的尽心回收。
复制:将内存分为两块区域:把左边这块区域不需要被回收的对象复制到右边,然后将左边的对象回收。
分代回收法:新生代用复制法,老年代用标记清除和标记整理
垃圾收集器:cms(concurrent Mark sweep)并发标记清楚:是一种以最短回收停顿时间为目标的收集器。
初始标记:快速的找到GcRoot所关联的对象
并发标记:跟踪GcRoot
重新标记:修改并发标记因用户程序变动的内容
并发清除
优点:并发收集,低停顿。缺点:产生大量碎片化空间
Java集合
1、collection——(list、queue、set)
list(ArrayList、linkedlist、vector、stack)
set(hashset、linkedhashset)
ArrayList:是基于动态数组实现的,实现了list、randomaccess,所以支持随即访问。
扩容:添加元素时会进入到ensurecapacityinternal()方法来保证容量是足够的,不高的话会调用grow()方法进行扩容,新容量的大小为oldcapacity+(oldcapacity>>1),也就是旧容量的1.5倍,扩容要调用arrays.copyof()把原数组整个复制到新数组,所以在创建数组是最好确定容量大小,减少扩容操作。
删除,调用system.arraycopy()将index+1后面的元素赋值到index上
序列化:transient修饰
vector:在ArrayList的基础上每个方法都加了synchronized,保证线程的安全,但是效率低。
linkedlist:是一个双向链表结构,新增和删除通过指针操作,查询如果指针离头近,就从头开始遍历,离尾巴近就从尾巴开始遍历。
hashmap:基于数组+单向链表+红黑树
实现原理:一般使用hashmap存储key-value类型的数据,当put时,首先会对key计算出hash值,通过hash值计算出放在数组的位置。
如果数组为空,直接放入,如果不为空发生hash冲突,先用链表把冲突的元素串起来,如果链条的长度达到了8,hash表的大小达到了64,则把链表转换为红黑树。
在hashmap由负载因子和初始容量影响性能,
扩容:首先得到新容量值和新的扩容阈值,默认都是原来的2倍,
根据新容量创建新的数组
把元素从旧数组迁移到新数组中。
currenthashmap使用了分段锁
hashset:不允许重复的集合,用hashmap的key来存放元素
linkedhashmap:linked保证了顺序性
线程
创建方式:1、实现runnable接口2、继承tread类3、通过线程池创建
生命周期:操作系统层面的线程状态
java初级必备面试知识
java线程状态
java初级必备面试知识
sql
索引:为了加速对表中数据行而创建的一种发散的数据结构
索引类型:全文索引、唯一索引、普通索引
索引数据结构:平衡二叉树,由一个个磁盘块组成的树形结构,每个磁盘块由数据项和指针组成
sql优化
1:负查询不能使用索引
2:like以通配符开头
3:数据区分不明显不能使用索引
4:字段上默认值不为空
5:不能让数据库做类型转换
mysql事务:原子性、一致性、隔离性、持久性
Redis:是一个nosql的内存数据库,使用string,set,hash,sortedset,list这5种数据类型将这些数据缓存在内存数据库中。
应用场景:缓存,共享session,分布式锁,消息队列系统
Redis过期策略:定期删除+惰性删除
内存淘汰机制:allkeys-lru:移除最近最少使用的key
Redis持久化机制:
RDB:快照形式,直接把内存中的数据保存到一个dump文件中,定时保存,AOF:把所有的对Redis的服务器进行修改的命令都存在一个文件里。
综合使用:用AOF来保证数据的不丢失,用RDB来做冷备,在AOF数据丢失时,RDB快速回复数据。
springboot
最大优势:约定大于配置
springboot启动时会去依赖的starter包中寻找resources/META_INF/spring_factories文件,根据文件中的配置去扫描项目中所依赖的jar包
根据factories的配置加载Autoconfigure类
根据@conditional注解的条件进行自动配置,并将Bean注入SpringContext
自动配置:启动注解是@SpringBootApplication包括(@configuration,@cpmponentScan,@EnableAutoConfiguration)是实现自动配置的入口,该注解通过@import注解导入了AutoConfigurationImportSelector在类中加载META-INF/spring.factories的配置文件,然后筛选出EnableAutoConfiguration为key的数据,加载到IOC容器中实现自动配置
消息队列
MQ消息中间间:为了解决异构系统
点对点模式:1-1
订阅模式:1-n
通配符模式:1x—nx
坑:
1:信息丢失:把当前数据存在磁盘里,持久化
2:接到2条一样的数据:在代码进行判断,查询是否被消费过
3:消息过多,后台信息清理

本文地址:https://blog.csdn.net/weixin_42017951/article/details/111940579

相关标签: java