2021-09-23 00:07:34
滴滴秋储面试包含一面和二面,一面以基础知识考察为主,二面侧重项目相关问题,且均涉及简单的手撕代码题,无HR面。具体如下:
一面(30min,纯八股,较基础)原理:它是一个很长的二进制向量和一系列随机映射函数。当一个元素被加入集合时,通过k个哈希函数将这个元素映射成一个k个位置的值,并将这些位置的值置为1。检索时,再使用同样的k个哈希函数对元素进行映射,查看对应位置是否都为1,若都为1则元素可能在集合中,否则一定不在。
使用原因:在项目中考虑使用布隆过滤器,可能是因为它具有空间效率和查询效率高的优点,适用于需要快速判断一个元素是否存在于一个大型集合中,且允许一定误判率的场景,如垃圾邮件过滤、缓存穿透防护等。
底层原理:ZSet(有序集合)的底层实现是跳跃表和压缩列表。当元素数量较少或元素长度较小时,使用压缩列表存储,以节省内存;当元素数量较多或元素长度较大时,使用跳跃表存储,以提高查询效率。
操作时间复杂度:例如,添加元素的时间复杂度为O(logN),查询元素排名的时间复杂度为O(logN),获取排名范围内的元素的时间复杂度为O(logN + M)(M为返回的元素数量)等。
慢查询优化:可以通过分析慢查询日志,找出执行时间较长的SQL语句,然后对其进行优化,如优化查询条件、减少不必要的列查询、避免使用子查询等。
索引设置:根据查询条件和排序需求,选择合适的列创建索引。一般来说,经常用于查询条件、排序和分组的列适合创建索引,但也要避免过度索引,因为索引会增加写入操作的开销和存储空间。
聚簇索引:索引的叶子节点存储了完整的数据记录,数据按照聚簇索引键的顺序物理存储。一个表只能有一个聚簇索引,通常主键就是聚簇索引。
非聚簇索引:索引的叶子节点存储的是聚簇索引键的值,而不是完整的数据记录。通过非聚簇索引查询数据时,需要先在非聚簇索引中找到聚簇索引键的值,然后再通过聚簇索引找到完整的数据记录,即需要进行回表操作。一个表可以有多个非聚簇索引。
题目内容:给定索引INDEX(a,b,c),分析以下查询语句的效率差别:
select a,b from table where a = 1 and b = 1
select a,b from table where a = 1 and c = 1
select a,b from table where a = 1 and d = 1
涉及知识点:最左匹配原则和索引下推。最左匹配原则是指在使用联合索引时,查询条件必须从索引的最左列开始,否则无法使用索引。索引下推是指在存储引擎层对索引中包含的列先进行过滤,然后再将过滤后的结果返回给服务器层,减少服务器层的处理压力。
分析:第一个查询语句可以使用索引,因为符合最左匹配原则;第二个查询语句中,虽然使用了索引的第一列a,但由于c不是索引的连续列,所以只能使用索引的第一列a进行过滤,不能使用索引下推;第三个查询语句中,d不是索引列,所以无法使用该索引。
区别:基本数据类型是直接存储数据的值,而包装类是将基本数据类型封装成对象。例如,int是基本数据类型,Integer是int的包装类。
包装类存在的原因:包装类可以提供更多的方法和操作,如类型转换、字符串转换等,并且可以在需要对象的地方使用基本数据类型,如集合类中只能存储对象。
空间占用:包装类占用的空间比基本数据类型大,因为包装类除了存储基本数据类型的值外,还需要存储对象的头信息等额外信息。
网络连接建立:客户端与服务器端通过TCP协议建立连接。
请求解析:Tomcat接收到请求后,解析请求行、请求头和请求体,获取请求方法、URL、协议版本、请求参数等信息。
请求处理:根据请求的URL和请求方法,将请求映射到相应的Servlet或JSP页面进行处理。
响应生成:Servlet或JSP页面处理完请求后,生成响应数据,包括响应行、响应头和响应体。
响应发送:Tomcat将响应数据通过网络连接发送给客户端。
select:可以监控多个文件描述符的I/O状态,但存在一些缺点,如监控的文件描述符数量有限、每次调用都需要将所有文件描述符从用户空间复制到内核空间等。
poll:与select类似,但解决了select中监控的文件描述符数量有限的问题,它使用一个pollfd结构体数组来存储要监控的文件描述符和事件,数组的大小可以动态调整。
epoll:是Linux特有的I/O多路复用机制,它通过事件表和就绪列表来实现高效的I/O事件监控。epoll不需要每次调用都将所有文件描述符复制到内核空间,而是只在添加、删除和修改文件描述符时进行复制操作,并且当有文件描述符就绪时,内核会将就绪的文件描述符添加到就绪列表中,应用程序只需要遍历就绪列表即可,减少了不必要的遍历操作,提高了效率。
Redisson分布式锁的原理:Redisson分布式锁是基于Redis实现的,它通过在Redis中设置一个键值对来表示锁,当客户端获取锁时,会尝试在Redis中设置这个键值对,并设置过期时间,如果设置成功,则表示获取锁成功;如果设置失败,则表示锁已被其他客户端获取,当前客户端可以等待一段时间后重试。释放锁时,客户端会删除这个键值对。
Redis实现转账操作的原子性:在Redis中实现转账操作,可以使用事务或Lua脚本来确保原子性。事务可以将多个操作打包在一起执行,要么全部执行成功,要么全部不执行;Lua脚本可以在Redis服务器端原子性地执行多个操作,确保转账操作的原子性。
项目数据库表设计:面试官会询问项目数据库表的设计思路,为什么要这样设计,以及在特定场景下的设计方案。例如,可能会给出一些与项目有关的场景,询问在这种情况下该如何设计数据库表。
其他项目细节:还会询问其他与项目相关的细节问题,询问时间将近半小时。
整体面试体验很不错,面试官友好,后续HR沟通也较为愉快。