1.Redis的数据结构你知道有哪些?
Redis本身是一种以键值对来存储数据的一种非关系型数据库,key只能是string类型,value可以是string,set,zset,list,hash,以及bitmap,GEO等。string的底层实现有3种,第一种是整数int,embstr(短字符串),raw(长字符串)。list底层有3种实现,第一种是ziplist(压缩列表),第二种是linkedList,第三种是quicklist。hash底层有2种实现,第一种是hashtable,第二种是ziplist(压缩列表)。set底层有2种实现,第一种是intset,第二种是hashtable。zset底层有2种实现,第一种是skiplist,第二种是ziplist。
string类型通常用于存储缓存对象,计数 list通常用于消息队列等 hash通常用于缓存对象(多个属性) set通常用于点赞,共同关注(求交集,,并集,差集) zset通常用于排行榜等
2.幂等是什么,如何保证
幂等性是无论我们这个相同的操作执行多少次,最终得到的结果都是一样的。
保证幂等性的方式有很多:
1.唯一标识符:给每一个操作都分配一个唯一标识符,每次进行该操作的时候就去检查这个操作是否被执行过了。
2.数据库约束:通过在数据库中给这个操作,添加唯一索引或者约束条件来确保某个数据项只能存在一次
3.缓存与标记:使用Redis这样的缓存工具来记录当前操作的状态。
3.线程安全的集合类有哪些
1.vector:线程安全的顺序表,但是现在已经很少使用了,是通过synchronized来修饰大多数方法来实现的。
2.copyonwriteArrayList:读写表:读的时候可以一起读,但是一旦有写操作,就会复制一张一模一样的顺序表进行写,之后再把这张表替换成最初的表
3.concurrentHashMap:线程安全的哈希表,通过给数组上的每一个元素增加一个分段所来实现
4.线程池的种类有哪些
1.singleThreadExecutor:只有一个线程的线程池
2.CacheThreadPool:理论上可以有无数个线程的线程池
3.FixedThreadPool:核心线程数和最大线程数一样
4.SchedeledThreadPool:可以设置定期任务的线程池,支持定时或者周期性去执行任务。我在实习的时候的负责板块就使用了这样的线程池
5.SingleThreadScheduledExecutor:只有一个线程的可以设置定时任务的线程池
5.线程池使用的参数如何设置
线程池主要是7大参数:核心线程数,最大线程数,空闲时间,空闲时间单位,阻塞队列,工厂模式,拒绝策略
参数如何设置就必须根据CPU密集型和IO密集型进行区分
CPU密集型:核心线程数和CPU核心数一致,最大线程数和核心线程数相同,任务队列通常使用有界队列
IO密集型:核心线程数是CPU核心数的2到4倍,最大线程数可以适当增加,任务队列使用无界队列
6.JVM内存模型说一下
JVM主要是将内存分配成了5个区域
1.程序计数器:私有的,最小的一块区域,记录下一条指令的开始
2.虚拟机栈:私有的,主要与方法的执行有关,当一个方法执行的时候,这个虚拟机栈就会给这个方法开辟一个栈帧,里面包括局部变量表,操作数栈去记录一些参数信息,返回类型,动态链接等
3.本地方法栈:私有的,与虚拟机栈类似,但是主要记录的是NATIVE的方法,也就是JVM底层实现的一些方法
4.堆:公有的,最大的一块区域,主要是存储一些实例的对象。从内存的角度上看,被划分为新生代区和老年代区,新生代又被划分为3个板块,分别为Eden区,S1区,S2区
5.方法区:公有的,主要存储一些常量和静态变量。
7.JVM调优参数有哪些
没了解过
8.堆区和栈区分别存什么
栈区与方法的执行有关:方法执行的时候,虚拟机栈会给方法开辟一个栈帧,里面包含局部变量表存储一些数据信息,同时还有操作数栈去执行对应的操作,同时栈帧中还会存储一些参数类型,动态链接,返回地址等,当方法执行完毕之后,栈帧也会随之销毁
堆区主要存储一些变量:一开始放入新生代的Eden区,使用过几次之后在S1和S2之间变换,最后进入老年代区,垃圾回收的主要地方就是堆区
9.tcp三次握手是如何进行的
TCP是面向连接的协议,进行数据传输的时候需要建立连接。
当服务端向客户端放松请求之后,会发送一个syn请求报文,进入SYN_SENT状态,服务端收到之后也会发送以个ACK+SYN的报文返回给客户端之后也进入SYN_RCVD状态,建立连接。客户端收到这个ACK+SYN报文之后,又发送一个ACK表示收到了,进入ESTABLISHED状态
注意:报文都会将SYN或者ACK的位置置为1
10.mysql隔离级别有哪些
1.读未提交:读取到其他事务没有提交的数据,会产生脏读,不可重复读,幻读等一系列问题
2.读已提交:读取到其他事务已经提交的数据,但是会产生不可重复读和幻读问题
3.可重复读:读取多次的结果都是一致的,会产生幻读问题
4.串行化:所有的操作的串行执行(对数据进行加锁),不会产生任何数据共享问题,效率较低
11.mysql的索引是什么
mysql有3种存储引擎,InnoDB,Memory,MyIsam,主要使用的是InnoDB,InnoDB的索引使用的是B+树这样的数据结构,因为B+树的叶子节点存储数据信息和主键信息,非叶子节点就全部拿来存储索引信息,这样就使得我们要查询一条数据的时候,先去非叶子节点查询索引信息之后就根据索引查到的信息去主键种查具体的数据,同时所有叶子节点还使用双向链表的方式连接,范围查询的速度也很快,这样使得千万条数据也能在3-4次IO就查询出来。
12.联合索引最左匹配原则是什么
简单来说:当我们使用到联合索引的时候,必须先满足最左边字段的索引,举个例子现在联合索引是A,B,C。我们必须要满足A的条件,例如A=10,B=10这样才能走索引,而如果我们的语句是B=10 and C=10,忽略了A的条件,就走不了索引
13.聊实习经历
因人而异
14.手撕:
最长公共前缀:14. 最长公共前缀 - 力扣(LeetCode)
代码:
public String longestCommonPrefix(String[] strs) {
int n = strs.length;
// 拿到第一个元素
String prefix = strs[0];
for(int i=1;i<n;i++){
// 拿到第i个元素
String ch = strs[i];
while(ch.indexOf(prefix)!=0){
// 切割
prefix = prefix.substring(0,prefix.length()-1);
if(prefix.isEmpty()){
return "";
}
}
}
return prefix;
}