2022年Java求职经历

2022.9.12,台州银行

电话一面:

1、java的gc回收机制怎么判断对象可以回收

对象的实例都已经被回收

类的classLoader已经被回收

该类对呀的java.lang.Class对象没有在任何地方被引用,无法通过反射访问该类的方法

可达分析法:从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GCRoots 没有任何引用链相连时,则证明此对象是不可用的,那么虚拟机就判断是可回收对象。

GC Roots的对象有:

虚拟机栈(栈帧中的本地变量表)中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI(Java Native Interface)(即一般说的Native方法)引用的对象
可达性算法中的不可达对象并不是立即死亡的,对象拥有一次自我拯救的机会。对象被系统宣告死亡至少要经历两次标记过程:第一次是经过可达性分析发现没有与GC Roots相连接的引用链,第二次是在由虚拟机自动建立的Finalizer队列中判断是否需要执行finalize()方法。

当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。

2、redis的主备机制

Redis的主从复制:

同一个Master可以同步多个Slaves。

Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。

Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求。

Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据。

在Slave启动并连接到Master之后,它将主动发送一个SYNC命令。此后Master将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Slave,以完成一次完全同步。而Slave服务器在接收到数据库文件数据之后将其存盘并加载到内存中。即连上之后,先进行一次全量同步。

此后,Master继续将所有已经收集到的修改命令,和新的修改命令依次传送给Slaves,Slave将在本次执行这些数据修改命令,从而达到最终的数据同步。后面进行增量同步。

 如果Master和Slave之间的链接出现断连现象,Slave可以自动重连Master,但是在连接成功之后,一次完全同步将被自动执行。

3、线程同步和锁的使用

synchronize

volatile关键字
保证了不同线程对这个变量进行操作时的可见性。
即一个线程修改了某个变量的值, 这新值对其他线程来说是立即可见的。
不保证原子性
即不能保证数据在多个线程下同时写时的线程安全
volatile最适用的场景: 一个线程写, 多个线程读
一个线程在修改某个变量的值,其他线程来读取该变量的值都是实时可见的


自旋锁与互斥锁的区别:线程在申请自旋锁的时候,线程不会被挂起,而是处于忙等的状态。

不可重入锁:只判断这个锁有没有被锁上,只要被锁上申请锁的线程都会被要求等待。实现简单

可重入锁:不仅判断锁有没有被锁上,还会判断锁是谁锁上的,当就是自己锁上的时候,那么他依旧可以再次访问临界资源,并把加锁次数加一。

自旋锁spinlock

4、java设计模式

2022.9.23 杭州一真医疗器械

1、java的collection集合的概念

d5d13d910e4044179c764bfe3b2ead18.png

hashmap实现原理

 a140bb190ac14129aa345058a1522235.png

 当链表长度大于阈值(默认为 8),转化为红黑树,当红黑树节点小于6,转化为链表。

2、线程创建的方法

Runnable Thread Callable

3、mysql的调优方式

选择最合适的字段属性
mysql在创建数据库的时候首先考虑数据库中的表越小越好,这样才能提高查询的速度。如果数据量过大,比如是以数万或者数十万为单位的,就需要考虑在建表时的字段长度。比如说在存储电话号的时候,如果将其写成CHAR(255),这显然会给数据库带来很多不必要的空间浪费,明明CHAR(11)就可以解决的问题。

使用连接查询(join)代替子查询
子查询的优点是可以使用简单的SELECT语句就可以完成逻辑较为复杂的查询动作,而且还能避免死锁的情况产生。但是有时也可以考虑使用连接查询来完成,毕竟连接查询不需要像子查询一样在内存中创建临时表,再从临时表中过滤数据,从而加快查询速度。

使用union联合查询
union本来就有联合的含义,它可以将多个SELECT语句的查询结果联合到一个查询中,从而替代了手动创建临时表的过程。而且union还有一个好处就是使用完了以后自动就删除了,一点也不占用内存空间。

通过事务来管理
事务是数据库调优时的一个老生常谈的概念,由于其4大特性,事务是不可避免的调优方式之一,它可以保证数据的完整性、一致性。可以用一句话来总结“去不了终点,那就回到原点。”

锁定表
尽管事务能够保证数据库的完整性和一致性,但是它本身其实也存在一些弊端。因为它本身具有一定的独占性,当事务没有执行完毕以前,用户发出的其他操作就只能等待,一直等到所有的事务都结束了才能继续执行。如果用户访问量特别大的时候,这会造成系统的严重延迟问题。
所以可以通过锁定表的方法,保证在没有执行到UNLOCKTABLES指令之前所有被LOCKTABLE修饰地表的查询语句不会被插入、删除和修改。

正确使用索引
索引是提高数据库性能的最常见的方法,能够正确地使用索引,能够大大地提高查询效率。
但是也不能够为所有的列都创建索引,因为它本身会占用内存,维护起来也很麻烦,它就是一把双刃剑,所以索引在使用的时候需要根据实际情况正确使用才行。

优化查询语句
在比较的时候尽量在相同的字段之间进行比较。例如不能将一个带有索引的INT字段和BIGINT字段进行比较;
已将创建了索引的字段上不要使用函数,那样会导致索引失效;
查询时不鼓励使用like语句查询,因为那会消耗掉一部分系统的性能。
 

mysql和nosql的优缺点

1a9ff0e8b2234f8d9ef7720c7bb0689e.png

 spring的理解

是一个轻量级的IOC和AOP的框架

IOC,依赖注入...

AOP,动态代理...

2022.9.27 

新奇点

java回收机制

通过可达性分析计算

如果没有被GC Roots引用的对象会被回收

虚拟根对象有哪些:

虚拟机中栈引用的对象

方法区中类静态属性引用的对象

方法区中常量引用的对象

本地方法栈中引用对象

回收算法

1、标记-清除算法

标记出所有需要回收的对象,统一回收

标志清除和会产生大量不连续内存碎片

2、标记-整理算法

在标记清除算法基础上将无需回收的内存移动到另外一边

分代

年轻代:edenty s0 s1,s0和s1之间来回移动,达到阈值之后,移动到老年代中 年轻代中回收叫做Minor GC

老年代:这里回收叫做Major GC

方法区

常见回收器

serial GC

paralll GC

CMS GC

G1 GC

线程池的理解

线程创建使用:继承Thread、实现Runnable,实现Calable

拼频繁创建和销毁线程需要消耗大量时间和资源,所以产生了线程池

线程池解决的问题:

1、线程池是一次性创建指定数的线程,放到线程池中便于管理

2、减少任务的调用开销,执行大量异步任务时对性能改善

3、每次使用完之后将使用完的线程放回线程池,减少销毁的时间和资源

线程池的创建使用Executors工厂

newCachedThreadPool() 无界线程池,自动线程回收

newFixedThreadPool 固定大小的线程池

newSingleThreadExecutor 单个后台线程

2022.10.9 招银网络一面

1、mysql优化措施,联合索引的方式(比如A、B、C三列联合索引,只是查询BC,能否得出结果)

调优手段:一、审视字段长度;二、连接查询代替子查询;三、union联合查询;四、使用索引

联合索引遵循最左前缀原则,所以查询BC索引不生效。

2、主线程和三个子线程之间的执行顺序,先执行子线程,等子线程执行完毕再执行主线程的实现

一、主线程sleep方式,主观,不推荐;二、使用Thread.join97c08722f21643eb99da224a434f6d1d.png

三、使用CountDownLatch,设置latch初始值,然后子线程执行完latch自减,直到为0 ,主线程才执行。

四、同步屏障CyclicBarrier,await到达屏障。

3、线程池的参数说明,线程池的拒绝

六个参数:corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、handler

拒绝策略四个:AbortPolicy(抛异常)、DiscardPolicy(静默丢弃)、DiscardOldestPolicy(喜新厌旧)、CallerRunsPolicy(调用者直接执行)

4、mybatis一级和二级缓存的概念

一级缓存sqlsession、适用经常查询不改值的场景,增删改时会被清空。

二级缓存同一个SqlSessionFactory对象创建的SqlSession共享其缓存。

5、spring事务的传播机制,实现方式

实现方式:编程式事务(代码中体现),声明式事务->传播机制:

5a0aba0464ae4c13bc860e54c29c093c.png

6、数据库和redis的一致性方式

一、更新缓存、更新数据库(数据库更新失败问题)

二、更新数据库、更新缓存(A线程更新数据库和缓存之间插入了线程B的更新操作)

三、先删除缓存,再更新数据库(A更新数据之间穿插了B线程的读取操作)解决方式:延迟双删

四、先更新数据库,再删除缓存(A读取数据库并写入缓存的过程中,插入了B线程写操作)解决方式:延迟双删

7、编程将两个有序数据合并

5926282ab72a442492faa595c7415eec.png

2010.10.10 字节一面

项目聊天

一、springboot的启动流程

  1. 首先从main找到run()方法,在执行run()方法之前new一个SpringApplication对象
  2. 进入run()方法,创建应用监听器SpringApplicationRunListeners开始监听
  3. 然后加载SpringBoot配置环境(ConfigurableEnvironment),然后把配置环境(Environment)加入监听对象中
  4. 然后加载应用上下文(ConfigurableApplicationContext),当做run方法的返回对象
  5. 最后创建Spring容器,refreshContext(context),实现starter自动化配置和bean的实例化等工作

二、springboot中mybatis是怎么连接sql语句这些的

1、自动注入mybatis,sqlsessionFactory

2、获取datasource并初始化并放入sqlsessionFactory

3、mapper文件中使用@Mapper注解

三、redis的持久化

RDB和AOF

RDB文件形式记录,恢复快但是存在数据丢失(5分钟一次)

AOF日志形式记录,回复慢但是不存在数据丢失(1s一次)

四、缓存穿透的原理,解决方式

缓存查询不到,直接查询数据库,大规模查询可能导致数据库打挂风险

解决方式:1、接口请求参数的校验;2、当数据库返回空值时,将空值缓存到redis,并设置合理的过期时间;3、布隆过滤器;存储所有可能的key;

缓存击穿

热点key过期后,大量查询导致数据库被打挂

1、增加互斥锁;一个线程获取锁查询完毕之后,写入redis,其他线程从缓存中查询。

2、设置缓存不过期或者后台有线程一直给热点数据续期

缓存雪崩

大量热点数据同一时间过期,大量线程查询直接导致数据库被打挂

击穿解决方案基础之上,将热点key过期时间离散化。

五、bean的注入方式

1、组件注解

2、@Component + @Bean

3、@Import(PlaceHolderClass)快速导入一个组件

4、使用Spring提供的FactoryBean注入

字节二面:

秒杀系统怎么设计

applovin一面

项目介绍

编程题:最长回文子串(暴力法和动态规划)

线程池的原理以及线程执行有几种场景

Threadlocal的原理

synchronized在jdk1.8做了什么优化

hashmap扩容为什么是2倍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值