面试相关的八股文都塞这里吧……也准备一些开发的,真的测试没萝卜坑,初级开发也考虑的……嘤嘤嘤

进程、线程、虚拟线程

进程:就是操作系统中的一个独立单元。进程之间是相互隔离的

线程:绑定到某一个进程内部的,是进程中的一个最小的执行单元。是cpu直接调度的

虚拟线程(普通线程调,没有可配置参数,用着简单)

        在java中,如果存在IO密集的任务时,线程个数不太好控制,如果用了虚拟线程,就不需要关注个数了。

        正常线程占用的内存资源在MB级别。虚拟线程占用的资源在KB资源。

        正常线程由CPU直接调度,存在上下文切换带来的时间成本,而且存在用户态跟内核态切换的时间成本。虚拟线程不是由CPU直接调度的,所以不存在所谓的上下文切换成本,而且没有所谓的挂起跟唤醒去切换状态的时间成本。

        虚拟线程无法解决CPU密集的任务,因为你CPU资源就那么多,不可能处理性能变高的。


重写、重载

重写:(Override)

重写是子类重写符类、父接口钟的方法,要求方法名,方法参数等必须跟父类一模一样。

但是返回结构需要适用父类方法,访问修饰符不能小于父类的方法。

重载:(OverLoad)

重载是在一个类里,方法名一致,方法参数不同。

返回结果,方法修饰符无所谓


String,Buffer,Builder

String:

        不可变长度的,使用 + 字符串连接,他也是构建一个全新的字符串,对内存占用比较大

        线程安全

StringBuffer:

        长度可变的,底层采用char[]去实现字符串拼接(1.9之后用的是byte,目的节约空间),可以规避String那种每次创建新的字符串

        线程安全的,加了synchronized,如果涉及到成员变量的拼接,记得用

StringBuilder:

        长度可变的,底层采用char[]去实现字符串拼接(1.9之后用的是byte,目的节约空间),可以规避String那种每次创建新的字符串

        线程不安全的,如果在局部变量自己玩的时候,可以用


Autowired和Resource注解

@Autowired

        Spring提供的

        默认类型注入,类型找到一个,直接注入;找不到或者找到多个,直接报错。

        如果找到多个要匹配,可以追加@Qualifier注解,指定名称。

@Resource

        Java规范提供的

        默认基于属性名注入,如果名字找不到,会再根据类型去找,类型到不到匹配的,也报错


Java中常见的集合

java中主要就是单列集合跟双列集合

单列集合

        List:存取有序,允许重复。底层有数组ArrayList和链表LinkedList集合(修改要用迭代器)

        Set:存取无序,不允许重复。底层是HashMap的key

双列集合

        Map:存储双列,key不允许重复,value无所谓。(建议扩展Hash)

        Map可以展开去聊一些底层实现,存储结构,线程安全问题等等。


线程安全的集合

        比较传统的线程安全集合:Vector,Hashtable,Collections.synch…这种,完全基于synchronized,锁全局,性能贼慢,基本不用

        CopyOnWrite系列:CopyOnWriteArrayList这种,他是利用空间换时间,来保证查询的时候不会阻塞,但是在写入的时候,依赖是基于lock锁保证线程安全的。

        Consurrent系列:这个优化的程度会比较大,一般会结合CAS+synchronized去保证写操作的线程安全,同事查询依然不会阻塞。建议扩展(ConcurrentHashMap)


对象为啥要有hashcode方法

        java中对象的HashCode方法就是提供给HashSet,HashMap这种集合,做一些hash寻址之类的操作。也可以配合eq做数据的对比。

       hashCode啥时候生成

        如果hashCode方法重写了,那你每次调用的时候,他才会生成对应的hash值。

        如果hashCode没重写,他固定就是你的全路径跟地址的信息,这个是不会变的。

        eq重写了,必须重写hashCode么?

                不是,根据通途考虑,何时重写,怎么重写


Session和Cookie

Cookie集合Session一般是实现会话的。

Cookie:

        存储在客户端

        存储由大小的限制

        不太安全,毕竟可以在客户端直接查看到

Session:

        存储在服务端

        存储大小理论上没限制,跟你的JVM内存走

        安全,毕竟在服务端

比较传统的项目会做会话控制的方式,现在用的不多,可以聊一些框架SpringSecurity,JWT……


HashMap,为啥key可以为null

一般这个问题最好是结合ConcurrentHashMap去聊

因为ConcurrentHashMap中,key-value不允许为null。而HashMap中没有这个限制。

因为ConcurrentHashMap一般是作为成员变量,多个线程都会操作,如果一个线程null存储特殊的标识,其他线程不知道

而HashMap是线程不安全的,必然是局部使用,就一个线程自己玩,所以就没关系


线程安全问题怎么解决

多个线程 同时修改 临界资源 导致的线程安全问题。

多个线程:就一个线程玩,自然没有线程安全问题,一些资源不是共享的,用ThreadLocal

同时修改:

        不让他同时修改,直接加锁!CAS,sync,lock……(扩展点一定在这,其次volatile也可以聊)

        不修改,final修改的常量

临界资源:不去做写操作,或者自己玩自己的局部资源,直接从根源解决问题。


Spring声明式事务时效情况

时效情况很多:

        方法基于private修改,导致AOP无法增强这个方法

        类没有实现的接口,并且基于final修改,导致AOP无法创建代理对象

        因为声明式事务默认搞RuntimeException,如果玩其他的自定义异常,也会失效

        异常被自己的try-catch了,没往上抛,导致异常增强不走

        在方法内部基于this.方式,或者方法内部搞多线程,都没走Spring增强后的代理对象

        确保数据源的目标数据库支持事务


事务传播特性

存在声明式事务增强的方法直接进行相互调用,存在事务传播特性的问题:

        REQUIRED:比如在一个事务里!走外层事务。(默认的)

        SUPPORT:随缘,有事务就加入外层事务,没事务,那就不走事务。

        REQIORED_NEW:不管怎么玩,都创建自己的新事物。

        NOT_SUPPORT:不走事务

        NESTED:嵌套事务的概念,自己回滚不影响外部,外部回滚,内部也回滚。

        NEBER:不走事务,你有事务,丢异常

        MANDATORY:走事务,没事务,丢异常


AOP实现的原理

可以从代理模式去聊。无非是

JDK动态代理:需要基于接口实现。被代理类必须要有实现的接口

Cglib动态代理:需要基于继承实现,被代理类不能被final修饰

JDK跟Cglib几乎大差不差,虽然Cglib基于字节增强去玩,但是JDK代理也在优化。

扩展:聊Spring的源码,BeanPostPricessir……


Spring中涉及的设计模式

单例、工厂、代理、观察者、模板、原型、责任链……

一个要求,聊到的,要知道大概再哪个位置用到,点到的必须知道在哪用的。


类加载器都有什么

java中自己带了三,自己也可以主动去实现,所以4钟

BootstrapClassLoader:默认 jre(jdk21里面没有jre了,包有优化)->lib下,比如 rt.jar

ExtClassLoader:默认 ext 目录下

AppClassLoader:默认 classpath 下

CustomClassLoader:指哪里打哪里

双亲委派:本质就是在加载.class文件时,会向上委托的方式,优先让最高层的ClassLoader去加载,如果加载不到,再往下去委派

代码实现本直就是基于递归走的。

第一次走是从Custom-App-Ext-Bs,这次走的过程是询问加载过没?加载过,直接用。

第二次是从Bs-Ext-App-Custom,这次是去加载,根据每个ClassLoader负责的位置,去加载。

核心目的是为了规避核心类被篡改。


JVM内存结构

一定要去区分好,java内存模式问的是jvm

从两个维度聊:

        线程私有:虚拟机栈、本地方法栈、程序计数器(记录的是下一条指令)

        线程共享:堆、方法区(方法区是JVM虚拟机的规范,一般实现是元空间)


垃圾回收算法

常见的三个

        复制清除:理论上将内存分为两片区域,只在一片区存放对象,一片满了,保留可用对应复制到另一片,然后清空当前片内存。空间浪费、回收速度快。

        标记清除:根据不同的算法,比如:三色标记对可用对象进行标记,将没标记到的,直接干掉。空间没问题,回收速度可以,但是有内存碎片问题。

        标记压缩、整理:根据不同的算法,比如:三色标记对可用对象进行标记,将没标记到的,直接干掉。然后整理空间,避免碎片化问题。空间ok,速度稍慢,没有碎片化问题。


常见垃圾回收器

从古老的,聊到新的

Serial New、Serial Old:非常远古的垃圾回收器,单线程回收,速度嘎嘎慢。

Parallel New、Parallel Old:JDK1.8默认的垃圾回收器,多线程回收,速度稍快,有STW。

ParNwe、CMS:CMS是并行的垃圾回收器,除了初始标记、重新标记位置需要STW之外,回收的时候是没有并行的,没有STW。

G1:分区回收,把整个堆分成上千个区域,每次就回收垃圾最多的位置,STW时间短。(GDK默认垃圾回收器)

ZGC:毫秒级别的回收,不需要做JVM调优相关的操作。

Shenandoah:速度也很快,毫秒级别的。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值