当前位置: 首页 > 后端技术 > Java

字节跳动经典--offer

时间:2023-04-02 00:09:11 Java

发表于我的博客,介绍17年毕业双非一书。面试抖音社区安全部,java面试。字节这边先自我介绍一下,问一下:数据库和中间件是做什么用的?答:mysql+postgres+kafka+redis问:你用过ThreadLocal吗?使用场景是什么?答:是的,在登录时记录用户的登录信息。Q:如何实现?答:在拦截器中解析token,然后将用户信息写入ThreadLocal。Q:还记得拦截器应该实现哪个接口吗?答:不记得了。Q:有的接口需要登录判断,有的不需要。如何处理?答:使用注解来标记不需要登录判断的接口。Q:知道ThreadLocal的原理吗?答:里面是一个Map,由线程持有,这就是线程安全的原因。ThreadLocal与Map之间存在弱引用,误用会导致内存泄漏。问:为什么会出现内存泄漏?答:GC时会回收弱引用。由于线程还处于活动状态,并且仍然存在对Value的强引用,所以value不会被回收,但是Map中对应的key会变为null。问题:什么时候请求key为null的数据(如何避免)?答:get/set/remove(和面试官意见不一致,坚持印象中的内容),使用ThreadLocal后及时remove。Q:线程池的核心参数是什么?答:五、核心线程数、最大线程数、最长活跃时间、阻塞队列、拒绝策略。Q:使用过哪些阻塞队列,使用场景有哪些?答:只用过ArrayBlockingQueue和PriorityBlockingQueue。Q:锁升级流程是怎样的?Answer:~Q:遇到过线上JVM问题吗?答:没有问:线上的JVM配置是怎样的?答:设置最大堆,最小堆,gc收集器为G1。Q:为什么要在线使用G1?答:我没有想过。..问:G1和CMS有什么区别?答:CMS是多线程并发的,采用mark-and-sweep算法,追求更快的GC速度。G1将内存分成小块,以追求更高的回收效率。Q:什么时候用G1,什么时候用CMS?答:不确定。Q:介绍一下这个项目和一些细节?回答:。..主要介绍一下项目背景和方案,然后说说有亮点的设计,比如为什么这样设计:我有一个设计是借用了HashMap链表的阈值变成红黑树,红黑树的阈值-黑树变成链表是6.思想(留一定缓冲空间,避免频繁变动)。然后可以谈谈这个方案的不足,以及改进的方向和思路。Q:hotkey的解决方法是什么?答:1.内存缓存2.拆分成多份Q:限流算法?答:窗口计数、漏桶、令牌桶(详细解释)问:分别有哪些使用场景?答:不确定。问题:如何在分布式环境中实现漏桶和令牌桶?答:令牌桶可以按照一定的速率写入redislist,然后接口会先拿到一个token。漏桶不知道。问题:mysql什么时候用主库,什么时候用从库?答:对于事务来说,master用于写操作,slave用于读操作。由于主从复制的延迟,需要立即知道的数据使用master。Q:主从复制是基于什么?答:binlog,抄八股文章。Q:主从复制有多少个线程?答:这里回答错了,线程应该是三种。Q:主从复制模式?答:同步、半同步、异步(介绍)。Q:有多少slave在等待半同步?答:一个。Q:binlog模式?(这里我应该问的是binlog的格式)答:不知道(应该是statement,row,mixed)算法:有增量数组,但是有重复的数字,重复的数字需要移动到阵列的后面就位。例如[10,11,11,12,12,12,13,14,15,15,15]移动[10,11,12,13,14,15,11,12,12,15,15]后前面部分自增有序,后面部分不需要自增有序。空间复杂度要求为O(1)。已经二十多分钟了。总的来说,表现不是特别好,但还是通过了面试。平时,我还是比较注重积累一些工具的使用场景。ByteTwoFaces自我介绍项目(很详细,各种细节,持续了半个多小时)Q:Rediszset结构,底层数据结构。Answer:ziplist,skiplist+dictionaryQ:skiplist的数据结构。答案:多层链表结构问:跳表的插入过程。答:一个小问题:层数怎么确定。Answer:CointossalgorithmQ:为什么要用cointoss,解决什么问题。答:应该是为了让层数分布更均衡(不确定)问:抛硬币正面和反面的概率是50%吗?答:不确定。Q:跳表的查询过程。答:一个小问题:数据重复呢?答:词典+跳表。分数不一样,再插一个。值一样,更新分数Q:你懂http协议吗?答:不太了解(略过)问:常见的索引类型?答:聚簇索引,非聚簇索引。Q:非聚集索引和聚集索引的数据结构是怎样的?答:使用B+TreeQ:B+Tree有什么好处?答:1、优化IO2、方便范围查询3、部分访问原理Q:BTree和B+Tree有什么区别?答:B树节点存储数据,IO较多。范围搜索支持不好问:非聚集索引和聚集索引有什么区别?答:非聚集索引只存储索引和主键。Q:ABC三个字段联合索引,什么时候不需要回表?答:只查询id+ABC这三个字段不需要返回表。Q:ABC联合索引,其中A和B>2且C=3,可以使用索引,为什么?答:A和B可以用,C不可以。最左前缀原则。(但不会归表,c=3会根据索引下推规则判断)Q:如何实现原子性?Answer:支持回滚,通过undolog实现Q:事务从开始到回滚如何实现?回答:一个简短的问题:undolog中存储了什么?A:逻辑日志,记录变化。问:持久性是如何实现的?答:保证crash-safe能力,redolog+binlog的两阶段提交。问:如何表现?答:二阶段提交流程(略)Q:事务提交成功,redolog可能没有写入磁盘?答:redologdoesnotfsync(redologflushing的三种策略)(事务没有commit也可能已经被放置)。Q:你能保证此时数据不会丢失吗?答:不能。设计题:设计一个幸运红包(同时春晚发红包)?答:(避免重复抢,红包发放问题,超发问题)略。算法:最长不重复子串总结:这边表现不错,基本回答了面试官问的所有问题。给我的感觉是面试官极其细致,详细到一个rediskey的键名怎么设计都需要讲清楚。字节的三面自我介绍项目Q:怎么解决死锁?答:锁定资源的顺序与优先级一致。(回答的不是很好)问:事务管理器是怎么设计的?答:threadlocal,aop加stack。方法的执行顺序保存在堆栈中。Q:Concurrenthashmap做了哪些优化?答:段锁改为cas+spin,synchronized。SQL题:公司部门表和部门员工表,找出部门数量最多的部门列表(人数最多的部门可能不止一个)答:selecta.dept_idfrom(selectdept_id,count(id)ascountfromdept_usergroupbydept_id)asa,(selectdept_id,count(id)ascountfromdept_usergroupbydept_idorderbycountdesclimit1)asbwherea.count=b.count设计问题:抖音重点设计,要求:1.判断是否注意对方。2、判断对方是否关注你。答:使用redis的hash维护自己的关注列表和粉丝列表。注意判断大V是否关注你,用你自己的粉丝类别来判断。设计问题:观看抖音的视频流。答:核心是readdiffusion和writediffusion。每个用户都有一个监视列表。小V发布视频,写进自己粉丝的观看列表(writediffusion)。大V发布视频,粉丝从大V的发布列表中读取数据(readdiffusion)。从观看列表中选择N个视频,然后从你关注的大V中选择M个大V,到他们的发布列表中获取一个视频。总共有N+M个视频分发给观众。Q:从大V到小V掉粉过程中如何避免频繁更迭?答:参考HashMap,把链表变成红黑树的过程,并设置一个缓冲区。例如:10万粉丝会让V变大,但是降到8万粉丝后V会变小。总结:瘦,还是很瘦。但是这三个方面更侧重于系统设计。很巧,面试前研究了很多feed流设计,自己的工作也和feed差不多,所以在这里回答的很好。这里没有算法题,可能是来不及了。总结一下三个面试,历时一个半星期,然后是HR面试,等待流程出offer。整个过程持续了三个星期,终于拿到了offer。心情低落后,这次面试很详细,面试官给我的感觉很好。感觉第一面是最难的,因为涵盖了知识点的广度和深度。