我的面试复盘总结(亚信科技)
2年经验,面初级开发
这次面试下来,我整体感觉还是比较稳的。面试官问的问题覆盖了Java基础、集合框架、项目经验、数据库、缓存、异常处理、AI工具使用等几个维度,我基本都能答得上来,而且大部分问题回答得还算准确和深入。
做得比较好的地方
基础方面,ArrayList和LinkedList的区别、扩容机制、HashMap的put流程这些八股文题目,我回答得比较完整,时间复杂度、扩容倍数、树化条件这些关键点都说到了,面试官没有追问就过了。
项目经验方面,面试官对我做的PDF生成模块问得比较细,从生成逻辑到文件存储到MinIO,再到生产环境使用情况,我都如实说了。虽然这个模块体量不大、并发不高,但确实是我自己做过的、已经上生产的真实功能,所以回答的时候底气是足的。
Redis那块,我说了用Hash存Token、用String存短信验证码,超时处理用拦截器校验,滑动窗口续期的设计思路也说了,面试官看起来是认可的。
值得一提的是我的个人项目,就是我为了恢复工作状态自己弄的那个优惠券小程序。从需求来源(自己翻真实需求)、需求分析(用了工具辅助)、开发到部署内网穿透、手机随时访问,这一套全流程我都是自己实操的。面试官听到这里明显比较感兴趣,我觉得这是加分项,因为能体现出我的自驱力和工程化能力。
AI工具使用方面,我确实在用Cursor和Trae,而且不是无脑用,我会review AI生成的代码,也发现过空指针之类的bug,还让Cursor帮我改过前后端bug。面试官应该能感觉到我是把AI当工具用,而不是依赖它。
暴露出来的薄弱点
有两个问题我答得不太好。
第一个是统一返回体的封装位置,我当时说“好像不是在那两个地方”,虽然方向没错,但表述不够清晰和自信。其实就应该直接说:在common模块定义一个Result泛型类,配合全局异常处理器使用,Controller层统一返回Result。
第二个是MySQL调优,当面试官问到底层SQL优化时,我只说了建立索引和分库分表,后面就接不下去了。这块确实是我的短板,没有真实处理过大数据量场景的调优经验。不过对于初级岗位,这个深度其实也还能接受。
还有就是AI模板化提问那个问题,我之前确实没意识到需要做这个,面试官提出来之后我当场就“懂了”,这个学习态度应该是给面试官留下了好印象。
整体评价
我觉得这次面试基本能过。基础题全拿住了,项目经验真实可讲,个人项目证明了我不是只会干活、还有自主学习和折腾的劲头。虽然在调优和分层设计上有些薄弱,但对于初级/初中级岗位来说,面试官大概率不会因为这个卡我。
我的思维能力、技术基础都没问题,项目上该有的我都有,哪怕让我设计我也能给出方案——只不过有些场景确实没实操过,但初级岗位不要求这个深度。
接下来如果有二面或者HR面,我会更有底气。
以下是问答记录
1、说一下 arraylist 和 linkedlist 它的区别,我们平常使用的过程中去怎么去选?
arraylist,第一个从他们的查找和增删来看,Arraylist 由于底层是动态数组。所以它查找的时间复杂度是 o1,但是,它的中间的增删由于涉及到后续的后续元素的移动,因此,它增删的复杂度能达到 on。在他的尾部进行增删的时间复杂度也是 o1,linkedlist 由于它的底层是一个双向链表。维护了一个头尾指针,因此,首先在头尾的中差很快,中间增删由于是一个链表需要进行定位,因此很慢。
从他们的存储这里来看,arraylist,它在它的尾部,通常会预留一定的空间,然后 linkedlist 的不会,它是会在新增节点的时候分配空间。
从它的使用场景来看,Arraylist 主要适合那种读多写少的场景,然后 linkedlist主要适合那种在头尾增删频繁的场景。我们绝大多数情况下使用的都是 arraylist。
2、arraylist如果要扩容的话,一般是扩多少?
初始容量是10,然后扩容的时候会变为原来的1.5倍。它会将原来数组的元素,全部都复制到新位置。
3、介绍一下哈希 map 它的一个 put 流程。
首先根据元素值计算出它的一个哈希值,定位它在桶中的位置,查看是否有哈希冲突。如果有哈希冲突的话,先判断先,没有哈希冲突,就用那个是就直接放进去,如果有哈希冲突。就通过链表的尾插法也插进去,发现 链表 的长度大于等于八,并且当前的容量是大于等于64的,它还会进行一个树化。
4、在项目中的一个全局的异常处理是怎么做的?
类声明上,如果我们要创建的异常类,是必检异常,比如说 io 异常类似的,那么我们就写一个继承自 exception 类的子类,重写它的一个构造方法,如果是。非检异常,比如说这种空指针异常类似的,我们就写一个继承自,runtime exception 类的一个子类。还要写一个全局的异常处理器去捕获非必检异常,然后给它封装一些前端能够识别的友好提示。
5、你们封装返回的话是有个统一封装,在 service 还是在 controller?(题目理解错了,以为问的自定义异常的统一返回哪里封装)
感觉统一返回的话好像都不是在这两者了。自定义了一个全局使用的类,throw一个 new一个return exception,这是定义的类,然后创建的一个对象异常对象。好像不是在那两个地方。
6、你说的 pdf 的布局组件是什么东西?
主要是基于我之前工作中实际的 pdf 生成功能做了大量的优化和重构,当时为了生成。证书这种单页的 pdf这种 pdf 有个特点,它的头部和底部是高度固定的,然后中间有一些可变列表,行数和内容都不确定。
7、就是一个生成 pdf 文件的系统?然后是后端的话就是动态去输入内容,你这边负责的话渲染?
做了一些增强,我复盘之后增强的。我让后端传的是一个对象进来。所有数据是他那边获取。
8、持久层的库是什么,比如说你生成的 pdf 里面的内容有在哪存储的?
我们当时按照项目来看,这样的,把 pdf 文件生成一个文件流,然后它上传到我们的文件中心的,根据文件的编号。是存在我们MinIO里面的。
9、只存了文件没有存文本吗?数据量大不大?
文本就没储存了,数据库里也存了文件的相关信息。基本信息嘛,这是数据库层面的基本信息。因为不同的业务来获取的数据不一样。下单到证书生成,可能一天生成几个到十几个不等,主要是因为我们。客户,首先他的首先单价很高,因此,客户数量比较少。所以就。并发量什么的也基本上没有什么并发量。
10、有上生产吗?是否上线使用?体量很少是吧?
已经用在生长环境,客户下单之后,已经使用了,到最近为止有好几年。体量较少。
11、你们文件服务器有没有,比如说满了什么的。对文件或历史数据有没有,不使用的清理。
这种场景目前还没有。对,没有,好像是用了三台还是两台机器来存的。
12、项目有多少开发人员?后端多少人?
项目开发人数最多的有30来人吧,这一个项目,因为它分了很多块。有小程序,有管理后台,还有主要还有一个 mes系统那一块是特别大。 前端有一个组,有7个人,后端有20来人。
13、你刚说的有小程序,你这边有也有设计?你给我讲一下小程序这个项目。90
也是我们项目中也有,我自己也弄了一个,首先项目的需求来源, 我是自己去找的那种,某个平台里面去翻的,翻到真实需求,然后去做了一些需求分析,由于需求分析这一块我不是特别擅长的,我是借助了工具的,帮他帮我分析的需求,根据这需求分析的内容,我做了一些出来,它主要是解决那种线下门店用纸质券,他记账什么的,折价什么的都不太方便。就这样用一个那种后台的领券管理,再到客户领券,再到优惠券核销全流程的管理体系,我就把它弄出来了,项目。
14、你自己去做的不是公司的项目?小程序的后管理端的那些配置什么的,这一套流程你都自己去实操,真实去能访问吗?
不是公司,主要是为了恢复我的工作状态,练了之后确实也有很好的效果。我现在已经部署内网穿透了,我现在可以在手机上,随时都能访问它,它的后台和管理系统,后台还有个小程序。都全,反正全流程都是弄通了的,部署也是一开始,开发阶段之前已经部署好了,什么数据库 Redis。这些。
15、你项目中用到的数据库一般都是啥?Mybatis防SQL注入的话一般是用什么关键字符?
Mysql,用井号加大括号,它就相当于是 sql 的一个参数占位符。然后 mybatis 会在运行之前,先替换成问号,去调用 prepare statement 里面的一个设置参数的方法。当然,顺序的把参数给放进去,这样的话,他就不会把你输入的字符串当成 sql 的一部分,只是当成一个参数。
16、Mybatis分页,怎么使用?
首先需要创建一个 mybatis 的拦截器,然后在里面,主要的目的是为了调用修改设置数据库类型的方法。然后使用的时候,先创建一个page对象,再用 select page方法。当然这个方法你也可以传入一个 lamba query rapper。因为它支持 lamba 表达式,然后 eq 还有 like 这些方法都可以检查你的字段名什么的,你调试起来非常方便。
17、 你们项目中有没有对数据库 mysql 数据库的一个调优部分,你自己有没有接触过?
我不知道把它的容器化那种算不算,就是我写了一个 mysql 的 dockerfile,然后当时我,我组长叫我写了,写了之后,利用它部署到我们 k8s 集群里面去了。里面,有东西,它那个数据卷挂载,这些东西,这些我当时没考虑到,也是我组长教的。
18、这是架构方面的,有没有对底层的 SQL 这方面的优化,比如说数据体量过大的话。怎么去保证它的一个增删改查这种效率?(分库分表只知道这个东西)
目前大,我可能标准做法大概这样的,第一种,是就是对那种查询比较频繁的,可以考虑建立一下索引。第二种我大致了解是一个可以分库分表!可以分到不同的数据库里面,然后。但是。大致的我想他。大致的,我确实也还没了解到那一步。
19、我看你里面也有用的 redis,Redis 的话,一般你项目中 redis 用来做什么,或者用了哪些数据类型?
项目中,主要是用的他 redis,redis 的一个哈希,主要是用来存我们的 token。Token 来存用户的登录信息用的。还有一个存我们的短信验证码,就这两块,当然我们 Token 存的它 key 是用的一个 jwt。管理存在是用户的详情信息用来快速获取用户信息用的。
20、你存登录信息,超时那一块怎么去处理的?
首先拦截器去获取拦截到 jwt,然后把 jwt 去 redis 里查一下,这个 key 是否能找到,如果我在查不到,直接这时候就返回给他用户。登录已失效。前端层面就是直接跳转到登录页面,当然我们设置这个 key 的时候肯定设置了过期时间,我们那过期时间当时是设置的是10个小时,你就能维持到我们整个开发。你早上登录到晚上下班的时间。
21、即将过期的时候操作是否会强制退出?你提到了滑动窗口过期,让你来怎么设计?
我每次登录的时候就去,每次不对,每次使用,每次。你让我使用到 jwt,你或许你看一下它的过期时间,如果发现他可能在将要过期。比如说他 ttl 啥的可能,那么只剩1分钟,我不确定 redis 能否看到 ttl,如果说低于1分钟,那么。这时候,我不知道可不可以去改过期时间,我只能说是把数据库的重新自己再重新查一遍,再设置一遍进去,但查库操作也只仅仅只在即将过期的时间段内。这样的话,他下次来的时候就也是一样的操作。
22、今年 ai 用的也挺多,你们实际中有没有去对 ai 的这一块使用?
我们当时那个团队是毕竟是在2023或者2024,也接触过 ai,那个时候主要是对它做来提问,或者说弄文件啥的,我最近,我自己也去使用了一下,比如说我跟你说那个小程序的所有的前端,还有它的后台系统的所有前端的,我全是用 ai 帮我弄的,只是我在中途的。是负责跟他联调的,中途也解决了很多开发的遇到的问题,当然他自己我也发现了,有些时候, 确实也会产生各种各 bug,比如说最经典的,我有一个优惠券的。显示嘛,明明我有些字段有个字段,表示了我这里是一个折扣券,让它显示几折的结果?他直接给我显示的显示成金额了,显示成金额0.7。本来我是想要再显示7折的嘛,有一个 cursor 还是挺厉害的,我之前叫他给我改后端 bug 改前端 bug,他甚至顺手帮我把后端的一个小 bug 给修了。
23、目前用到的工具就是刚说的。cursor还有其他的吗?你用是怎么个形式用是插件?命令?其他方式?
才用过那个字节的那个trea那个用它,主要是因为它免费嘛,一开始有几天用的还是挺好的。我直接下载了他官方软件,打开那个项目。也就是一个跟他们自己的一个 ide 开发工具。
24、你用 ai 生成过代码吗?一般都是生成什么什么类型代码?
那种它的功能较为重复的,比较简单,那种只有 cud 的功能,那些功能模块,比如说那生成一些那种固定的,实体类啥的。我告诉他数据库的字段是什么,为了让他写一下,增删改查我写过一个模块,核销的模块。当然也发现了, 反正用起来就发现它有时候会犯一些很小的问题,比如最经典的一个空指针那里它不判空,就它从 redis 里获取信息之后,直接使用返回的对象开始操作,它也没有判空什么的。
25、你自己有没有总结过一些一些模板?比如说你给他喂的信息?喂什么格式的什么什么模板信息来要求他?(确实没弄过)
确实倒是没使用到那一步,原来还需要,懂了,原来还有还需要有这样一种操作,可以去约束一下他?懂了。以后注意一下。