常见的面试题
- 1.TCP,http,https的区别
- 2. 简单描述再浏览器输入一个地址可能经过的链路?
- 3.什么是类加载器?列出三种类加载器的用途
- 4.举例说明实现List接口的数组,队列、链表、栈等数据结构的一种实现,说明各自特点,结合项目举例说明场景
- 5. 什么是序列化与反序列化?
- 6. 为什么将敏感数据存储在字符数组中,而不是字符串中?为什么java的String是不可变的?
- 7.简述三种内存溢出的情况?并给出解决方案
- 8.在浏览器输入一个网址到界面展示的中间过程
- 9.常见的线程池?具体使用场景
- 10.数据库四大特性,和事务隔离级别优缺点
- 11.Ngix的转发策略
- 12.对索引的认识
- 13.redis的三种内存淘汰策略,使用场景
- 14.使用java中wait、notify,notifyAll在java中实现生成消费者模式?
- 15.redis 中高可用方案的优缺点
- 16.简述java垃圾回收机制
- 17.如何捕获另外一个线程的异常
1.TCP,http,https的区别
TCP是传输层的协议,主要解决数据再网络中如何传输,http和https是应用层的协议,除了传输数据外,主要解决再如何包装数据,
2. 简单描述再浏览器输入一个地址可能经过的链路?
1.客户端发起请求->浏览器dns缓存->本地dns缓存-dns解析获取IP(可能是代理)-> 达到代理,负载均衡策略转发->到达网关服务-》解析URL,找到服务查询-》跳转到具体的服务
3.什么是类加载器?列出三种类加载器的用途
类加载器,用来加载class字节码文件,如下:
- 启动类加载器Bootstrap ClassLoader 用来加载java的核心类,无法被java程序直接引用
- 扩展类加载器:extensions classLoader,用来加载扩展的java类库
- 系统类加载器:System ClassLoader 根据java应用的类路径加载java类可以通过 ClassLoader.getSystemClassLoader()来获取它
4.举例说明实现List接口的数组,队列、链表、栈等数据结构的一种实现,说明各自特点,结合项目举例说明场景
数组实现: ArrayList,队列、链表:LinkedList,栈:Stack
数组特点:快速通过数组下标定位,方便查询。
链表特点:方便删除修改数据
队列特点:先进先出
栈的特点:先进后出
队列的使用场景:一个属性结构的数据,如公司部门结构表。需要对部门进行同级别优先遍历时,需要使用队列的先进先出实现。
5. 什么是序列化与反序列化?
序列化就是将对象转换成可以存储或传输的形式,如转化成字节,xml、json等,将这个过程返过来转化成对象的过程就是反序列化
6. 为什么将敏感数据存储在字符数组中,而不是字符串中?为什么java的String是不可变的?
字符串是不可变类型,持有引用即可获取到值,二字符串数组每次实例化返回的对象都不相同,所以字符数组更加安全
1.因为是不可变的,可以使用字符串常量池来节省大量的空间和效率
7.简述三种内存溢出的情况?并给出解决方案
- 栈溢出,递归调用深度过高时会出现
- 堆溢出: -Xmn -Xms -Xmx 设置
- 永久代:元空间溢出 -XX:MaxMetaspaceSize=100m
8.在浏览器输入一个网址到界面展示的中间过程
9.常见的线程池?具体使用场景
- 固定线程长度线程池
- 缓存线程池
- 单线程线程池
- 指定核心线程池和最大线程数与队列大小的线程池
10.数据库四大特性,和事务隔离级别优缺点
四大特性:1.原子性、2.一致性、3.隔离性,4.持久性
事务隔离级别:
- 读未提交(Read uncommitted)可出现脏读,当A事务写入数据未提交事务时,B,这时候读的数据就是脏读
- 读已提交(Read committed)不可重复读,当事务A在修改数据未提交事务时,B在修改前与修改未提交两次读取的数据不一致
- 可重复读(Repeatable read) mysql默认,可出现幻读,
- 串行化(Serializable )可避免 脏读、不可重复读、幻读 的发生。 效率低,相当于锁表
脏读
当A事务写入数据未提交事务时,B,这时候读的数据就是脏读
不可重复读
当事务A在修改数据未提交事务时,B在修改前与修改未提交两次读取的数据不一致
幻读
在事务A新增/删除了几行数据未提交事务时,事务B在新增/删除前读取与未提交事务期间读取的数据行数会不一致的情况。与不可重复读的主要区别在于,不可重复读在于修改数据,幻读在新增/删除行。
11.Ngix的转发策略
1.轮询、IPhash,权重定义
见详解Nginx转发策略与反向代理
12.对索引的认识
13.redis的三种内存淘汰策略,使用场景
- allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(常用)
- volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。
- volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key(这个一般不太合适)。
14.使用java中wait、notify,notifyAll在java中实现生成消费者模式?
package org.chenglj.common.concurrent;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ThreadLocalRandom;
/*
* @Description
* @Date 2021/6/13 17:40
**/
public class ProductTest {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
new Thread(new Product(list)).start();
new Thread(new Consumer(list)).start();
}
}
class Product implements Runnable{
private List<Integer> list;
public Product(List<Integer> list){
this.list = list;
}
@Override
public void run() {
while (true){
synchronized (list){
ThreadLocalRandom random = ThreadLocalRandom.current();
if(list.size() > 0){
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
int next = random.nextInt();
list.add(next);
System.out.println("生产者生产产品:"+next);
list.notify();
}
}
}
}
class Consumer implements Runnable{
private List<Integer> list;
public Consumer(List<Integer> list){
this.list = list;
}
@Override
public void run() {
synchronized (list){
while (true){
if(list.size() == 0){
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Integer current = list.remove(0);
System.out.println("消费者消费:"+current);
list.notify();
}
}
}
}