小厂面试面经分享,攒人品

1.自我介绍
2.项目是在网上学习的还是在学校有用到?(面试官说的方言,有点听不太清,所以当时听成了网上学的还是自己做的)
“我是在网上学习的过程中了解到这样一个项目原型,并利用这个业务进行了自己的思考与开发”
3.项目中比较难的工作?
“我在项目中比较难的主要是技术的选型以及迭代,比如超卖问题,起初是没有考虑到在多线程情况下是会超卖的,后面加了悲观锁,就是用的本地锁。然后就是在集群情况下本地锁失效了,改用分布式锁。再后面一步步对锁进行优化,使用lua脚本、采用RocketMQ进行异步下单等。还有就是我的agent模块,需要我详细说吗?”
4。那你项目是你一个人做的,还是跟其他的人一起做的。
”我自己做的“
4.描述你那里提到的滑动窗口顺流AOP这一块,你是怎么实现的?
“我是通过Redis的Zset实现的,通过Zset的排序功能,对时间戳进行一个排序,保留最近时间段内的记录,对于过早的记录可以删除。如果窗口内的记录个数到达传参进来的窗口大小就直接进行拦截,否则放行。AOP的话我是通过自定义注解实现的,实现自定义注解之后将这个注解放到想要进行限流的类上,比如我的每一个controller上我都放了一个这个自定义注解进行限流。然后这个限流的参数是可以自定义的,比如秒杀接口可以限制每人每分钟五单,我设置的是每人每分钟一单,这样可以省去部分的一人一单校验开销嘛。对于其他接口就设置一个合理的、适合那个接口的参数。”
5.AOP你说有切入点嘛,对吧?你切入点里面了哪些业务?
(这里感觉和之前问的有点重复)又答了一遍哪个zset。
6.然后用了哪些注解?
(这才知道他想问的是AOP用了哪些注解)答了Pointcut、around、before、after。
7.什么是多态?
“多态就是编译期间是无法知道这个引用具体指向呢是哪一个实现类的,然后在运行程序运行期间才能知道这个父类指向的具体是哪一个子类。并且这个父类可以调用子类的一些重写的方法,在实现的时候,不同的子类实现的是不一样的。在程序运行期间才能确定这个方法到底调用的是哪个。”
正确答案:多态指程序中定义的引用变量所指向的具体类型和引用变量发出的方法调用在编译期并不能确定,而是在程序运行期间才确定。多态有三个必要条件:继承、重写、父类引用指向子类对象
8.为什么要用多态?
(完蛋了,忘了)答了可能是为了灵活性
答案:多态可以提高代码的扩展性和复用性,是很多设计模式、设计原则、编程技巧的代码实现基础。比如策略模式、基于接口而非实现编程、依赖倒置原则、里式替换原则、利用多态去掉冗长的 if-else 语句等等
9.那你在你的业务代码里面,你是怎么实现多态的?
(完全答偏了,答了负载均衡策略的三个具体实现)
10.创建线程有哪几种方法啊?
“我用的比较多的是直接使用线程池,不过线程创建的底层实现主要有三种方法,第一种是new一个Thread去创建,第二种是继承rannable接口,实现run方法,第三种是future,这种方式可以接收返回值(第三种忘了具体实现了其实,不过前面其实也答的不太对,答案应该是1.继承Thread,重写run方法,2.实现runnable接口,重写run方法,3. 实现Callable接口,重写call方法  )。”
11.那为什么到线程里面会出现线程不安全的问题?
”单核下线程并发执行,给每个线程分配的时间片如果用完了那就会切换成其他线程,或者在多核情况下线程可以并行执行,无法保证一个线程在执行代码块的时候没有其他线程到来。“
答案:线程不安全,核心原因就是多个线程同时去修改同一个共享可变变量,主要由三个问题导致:
1. 原子性问题像 i++ 这种操作,底层是读 - 改 - 写三步,不是一步完成的,线程切换会打断执行,导致数据计算错误;
2. 可见性问题线程会把变量读到自己的工作内存里修改,修改后不一定立刻同步回主内存,别的线程就看不到最新值;
3. 有序性问题JVM 为了优化效率会做指令重排,单线程没问题,但多线程下会打乱执行顺序,引发逻辑错误。
12.ThreadLocal你在哪里用到呢?
(不会,没想出来)
 答案:ThreadLocal 核心作用是实现线程内的数据隔离,存储当前线程的私有数据,做到线程独享、不共享,避免线程安全问题,也不用频繁传递参数。  最常用的场景时存储用户登录上下文信息。在登录拦截器 / 过滤器里,把当前登录用户的 ID、用户信息存到 ThreadLocal 中,后续在 Controller、Service 等任意层直接获取,不用层层传递用户对象,而且每个请求对应一个独立线程,用户信息不会串线程。  
13.你的那个AOP的原理是什么?
 ”AOP 的核心原理是动态代理,在不修改原有业务代码的基础上,为目标对象生成代理对象,在目标方法执行前后,织入日志、事务、权限校验这类横切逻辑。  “
14.Bean的注入有哪几种方式?
”有三种方式,第一种是构造器注入,第二种是setter方法注入,第三种是字段声明注入“
15.拦截器和过滤器有什么区别?
(完蛋,不了解过滤器)”拦截器的话主要就是拦截一些我用到的就是拦截一些接口的,就是拦截某些接口,进行一些逻辑判断。这过滤器的话,它是已经被淘汰掉了吗?不太了解啊。“
答案: 过滤器是容器层面的请求拦截,更早、范围更广;拦截器是Spring 框架层面的拦截,更灵活、能和 Spring 生态结合,项目里做登录校验、日志我一般优先用拦截器。  
16.我看你用了AI那个吧,对吧?你是在哪里用的,怎么用的啊
17.完全二叉树是什么?
(没背过,隐约感觉数据结构课上讲过)”叶子节点都在同一高度的树“
答案:除了最后一层以外,上面每一层的节点数量都达到最大值;最后一层的所有节点,都连续靠左排列,中间没有空缺。
18.二叉树的遍历有哪些方式?
”先序遍历,中序遍历,后序遍历,还有利用队列进行一个层序遍历“
19.什么情况下会用到先序遍历?
”查找某个具体数字的时候,可以以一个O(logn)的复杂度找到这个数“
答案:
● 复制 / 克隆二叉树先创建根节点,再递归创建左、右子树,能完整复刻原树结构。
● 二叉树的序列化按先序顺序存储节点,后续反序列化时可以直接还原出整棵二叉树。
● 前缀表达式求值前缀表达式(波兰式)的计算逻辑和先序遍历一致,先算运算符,再算左右操作数。
● 目录树、文件树遍历展示先展示父文件夹(根),再展示子文件夹 / 文件,符合日常文件浏览的逻辑。
20.快速排序的思路是怎么样的?
”快排就是我们先取一个值,然后通过那个双指针,然后呃把这个值插入到他该他该在的位置,然后这样就把这一整个数数组给分成了两段,一部分是比它小的,一部分是比它大的,然后这样就可以两两段进行一个分治,然后每一段再去取这么一个值,然后把它通过双指针,然后来找到它的位置,这样不断的缩小它排序的范围,最终排序。
21.快速排序什么情况下会出现O(n2)复杂度
“每次都取到了最大值或者最小值,导致该数无法将整个数组分成大小相等的两块”
面试官:就是逆序的情况是吧?
(当时没反应过来,现在想想面试官是在提醒我)
22.什么情况下会遇到抽象类啊?为什么要有抽象类?
(有点忘了)“抽象类的话主要是用于继承。有一个就是有一个父子的继承关系的时候,会用到抽象类”
答案:
1. 抽取共性、复用代码:把多个子类相同的属性、通用的方法抽到父类里,避免重复写代码;
2. 制定规范、强制约束:用抽象方法规定子类必须实现某些行为,子类不实现就编译报错,保证代码结构统一。
而且抽象类不能被实例化,避免父类被错误创建,只作为被继承的基类使用。
多个类有共同特征,但核心行为不同时会用到继承
23.那为什么不用普通类继承呢?
 答案:普通类可以直接实例化,而父类往往是抽象概念  , 普通类无法强制子类必须重写方法  , 代码语义更清晰  
24.你用过哪些设计模式啊?
“测试模式我用用的比较多的是一个是工厂模式,还有一个是策略模式。
这个工厂模式的话就是。建造一个工厂方法,然后用户不用关心里面呃里面就是这个工这个这个这个构造的具体实现,然后只需要进行传参,然后就可以通过这构通过这工厂方法来呃呃就是创建一个获取到一个对象了,还有个是策略方法。我这个我刚才说的这个一致性哈希的那个负载均衡策略。它那个里面实际上是呃就是我实现了三种负载均衡策略嘛,一个是一致性哈希,还有一个是轮询的。还有一个是随机的,他们三个实际上每个都是一种策略。然后在这个呃在这个策略策略模式中,就是最终想要调用的是哪一个,然后就可以去。直接就把我实现的这个策略给传进去就可以了。”
25.你遇到最复杂的问题是什么问题?

无算法题#牛客AI配图神器#
全部评论
感觉进去有戏啊
点赞 回复 分享
发布于 03-26 23:26 北京
感觉聊的真的多啊
点赞 回复 分享
发布于 03-25 23:17 北京

相关推荐

评论
1
收藏
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务