1 自我介绍
2 千里IT协会经历
总结:这个应该是在看面试人的潜力和领导力,所以可以适当吹牛逼
2.1 这个协会是你们学院的还是你们系的?
答:学院的
2.2 你为什么大二就能做到会长,你让大三大四的学长学姐怎么看呢?
当时的回答:因为我们协会的制度就是这样的,大三大四的学长学姐要么毕业要么在找工实习或者考研。
比较好的回答:我们协会的会长选拔制度是这样的,大二和大三的都可以申请成为会长,先要经过考试,然后经过大四的学长学姐面试,最终取得最好成绩的人当会长,我的能力比较突出,在大一期间带领大家参加过创新创业比赛,还参加了学校思政小程序的开发,然后还帮老师做了一些事情,所以就很幸运的成为了会长
2.3 协会是怎么个组织形式啊
答:有java、web前端、设计、小程序开发以及运营组,正副组长负责各个组的培训工作,还有招生工作,会长和副会长负责在组长忙碌的时候代替他们的培训工作,会长平常还会发送一些招聘、比赛的东西到群里,然后学院会组长比赛啊什么的,会组织大家参加,拿奖
2.4 日常会做一些什么样的活动呢?
答:
(1)每周末会给大家讲解一些最新的框架,教他们怎么用,我当时的理念是先教它们怎么用,先熟悉起来,感兴趣之后再推送一些好的深度文章给他们进行分析,如果一开始就给他们将复杂原理,它们可能没什么动力;
(2)平常学院会组织比赛,会带它们积极参加,比如创新创业比赛,一些作品的实现,我们组员会参与,比如写一些网页什么的
(3)其次,学校的思政开发小程序是我们参与开发和维护的。
2.4 你们做的最大的一个成果是什么?
答:马克思主义学院的思政答题小程序是委托我们做的
2.5 一到两年之间如何把技术提升到可以给别人培训的高度呢?(没答到点子上)
答:
(1)计算机薪资高嘛,所以觉得做码农还不错,至少不排斥
(2)有足够的动力,比如我当时想要提升自己的各课程的绩点,所以努力学习基础知识
2.6 你怎么让自己的能力在一年内达到做小牛这样的高度呢?
答:
(1)驱动力足够强,2.5说的
(2)网上有很多开源的java课程,花一两个月就大概能学完这些crud课程,学会使用最基本的框架,随后又跟着课程做了一个全栈开发的项目,打通了前后端开发的能力
(3)找学长学姐,他们会给我们一些,知道哪些是目前最流行的技术,我知道后自己会主动去找资料学习
(4)看知乎上写的一些总结帖子,他会就某一个点讲解的特别深,这使自己对语言的理解也加深
2.7 我很好奇,你们现在不看书了嘛(其实可以加上去)?
答:因为那个时候书本讲的东西很泛,而且找不到重点,视频的话就一般之讲解最精华的部分,而且通过图文并茂的方式,你会很容易记住;视频也比较能速成
3 秒杀
3.1 秒杀系统这个项目主要是在哪些方面对你有较大的提升?
答:
“秒杀系统”是一个在互联网购物高峰时期经常出现的特殊促销模式,通常用于某些大促销活动,如“双十一”等,其核心是在一个非常短的时间窗口内,提供大量折扣商品供用户抢购。由于有大量的用户同时在线,并试图在第一时间内购买限量的优惠商品,所以秒杀系统的技术要求非常高。对于开发和运维这种系统的团队,以下几个方面可能会得到较大的提升:
-
高并发处理能力: 秒杀活动的特点是在短时间内有大量的请求涌入,如何有效地处理这些请求、确保系统的稳定性是一大挑战。团队在这方面会积累很多经验。
-
数据库优化: 由于有大量的用户访问,数据库的读写请求会非常频繁。如何优化数据库的查询、减少数据库的锁冲突、使用合适的数据结构等是必要的。
-
缓存策略: 利用各种缓存技术,如Redis, Memcached等,来减轻数据库的压力,提高系统响应速度。
-
分布式系统设计: 秒杀系统通常需要多个服务器协同工作,如何设计一个有效的分布式系统,确保数据的一致性,是一个核心问题。
-
流量控制与限流: 利用各种策略和工具来确保系统不会因为过大的流量而崩溃。
-
安全性: 防止各种恶意攻击,如DDoS攻击、脚本自动抢购等。
-
用户体验: 虽然技术层面很重要,但用户的购物体验也是关键。如何在保证系统稳定性的同时,给用户一个良好的购物体验也是需要考虑的。
-
监控与故障恢复: 在高峰期,如何快速地发现问题、定位问题、并修复问题是很重要的。
通过开发和运营秒杀系统,团队在以上这些方面都有可能获得大量的经验和提升。
3.2 你刚刚说了高并发的情况下,如何保持系统的可用和稳定,那能简单给我说一下嘛,你自己总结出来了哪些手段呢?
答:
(1)多级限流:nginx,api网关,rpc框架、接口的用户限流
(2)缓存:redis预减库存和内存标记
(3)消息队列:削峰填谷
其实还可以答:
(4)服务降级和熔断:避免服务雪崩
(5)监控和日志:在必要的时候利用监控可以添加机器和资源,提高负载上限
下面是gpt4给出比较完整的回答:
在面对高并发的场景,保持系统的可用性和稳定性是至关重要的。以下是我总结的一些主要手段来处理这种情况:
-
负载均衡:通过使用如Nginx, HAProxy等负载均衡器,将流入的流量均匀分配到多个服务器上,这样单个服务器的压力就会降低。
-
限流与熔断:限流是限制系统接入的请求量,确保系统在可控范围内运作。熔断则是当某服务出现问题时,暂时断开请求,防止这个问题进一步扩散或影响其他部分。
-
缓存策略:通过使用Redis, Memcached等缓存工具,减少对数据库的直接访问,降低数据库压力,并加速请求的响应时间。
-
数据库优化:
- 读写分离:使读操作和写操作分布在不同的服务器上,平衡负载。
- 数据库索引:优化查询,加速数据检索。
- 分表分库:当单个数据库难以承受巨大流量时,可以将数据分散到多个数据库或表中。
-
异步处理:对于非即时性要求的操作,如日志记录、消息发送等,可以使用消息队列(如RabbitMQ, Kafka)进行异步处理,不阻塞主流程。
-
扩容与弹性伸缩:随着流量的变化动态增加或减少服务器资源。云服务提供商如AWS, Azure等通常会提供这类服务。
-
应用性能监控(APM):使用工具如New Relic, Datadog等监控应用的性能,及时发现并解决瓶颈。
-
代码优化:良好的代码结构和算法可以大大提高系统的处理能力。周期性的代码审查和性能测试可以发现并修正潜在的问题。
-
容灾备份:建立冗余系统和备份,当主系统出现问题时,可以快速切换,确保服务不中断。
-
安全防护:使用防火墙、CDN等工具抵御DDoS攻击,保证系统在恶意攻击下仍能稳定运行。
这些手段需要根据具体业务和技术架构进行综合考虑和应用,以确保系统在高并发下仍能稳定工作。
3.3 这有什么隐患呢?用和不用的各自优缺点
答:
(1)缓存和数据库的数据同步问题
(2)缓存击穿问题
(3)超卖问题(其实用和不用都会导致)
gpt4给出的合适答案:
对于上述的高并发应对措施,虽然它们能够有效地提高系统的可用性和稳定性,但同时也存在一些潜在的隐患。以下是一些常见措施的优缺点以及潜在隐患:
-
负载均衡:
- 优点:平均分配流量,防止单点故障,增加系统的可用性。
- 缺点:增加了系统复杂性,需要维护负载均衡器的配置。
- 隐患:如果负载均衡器本身出现问题,可能会导致整个系统不可用。
-
限流与熔断:
- 优点:防止系统过载,提高系统的韧性。
- 缺点:可能导致正常的请求被拒绝。
- 隐患:过于保守的设置可能导致大量合法请求被拒绝;过于宽松的设置则不能有效地保护系统。
-
缓存策略:
- 优点:提高数据访问速度,减少数据库的压力。
- 缺点:增加了数据一致性的挑战,需要维护缓存策略。
- 隐患:缓存击穿、缓存雪崩、缓存脏读。
-
数据库优化:
- 优点:提高数据库的处理能力和响应速度。
- 缺点:增加了系统的复杂性,可能需要更多的维护工作。
- 隐患:数据不一致,分库分表后的跨库操作复杂。
-
异步处理:
- 优点:非阻塞操作,提高系统响应速度。
- 缺点:可能增加系统的复杂性,需要额外的组件来处理异步任务。
- 隐患:消息丢失、消息重复处理。
-
扩容与弹性伸缩:
- 优点:动态适应流量变化,高效使用资源。
- 缺点:增加了成本,需要对资源进行监控和管理。
- 隐患:自动伸缩策略不当可能导致频繁的资源变化,影响稳定性。
-
安全防护:
- 优点:防止恶意攻击,提高系统安全性。
- 缺点:可能影响系统性能,增加了管理和维护的复杂性。
- 隐患:安全策略和工具配置不当可能导致防护失效。
在考虑使用上述措施时,应该根据具体业务和技术环境进行权衡,并持续监控和调整,以确保系统的稳定和高效运行。
3.4 超卖问题的根本原因是什么?
答:
- 数据竞态条件(Race Condition):在并发环境下,多个进程或线程在没有适当同步的情况下同时读写某个共享数据,导致数据的不一致性。例如,在秒杀活动中,当两个用户几乎同时购买最后一个库存商品时,由于竞态条件,系统可能会错误地认为还有库存,并允许两个用户都成功购买,从而导致超卖。这种情况如果没有上锁,会导致大范围超卖
- 针对(1)中的问题,所以一般会进行加锁,但是这种情况还是会导致少量的超卖,为什么呢?根本原因是在事务释放之前锁提前释放了,是一个事务的一致性问题
3.5 怎么解决超卖问题(我对整个业务上了锁,事实上并不好,粒度可以更细点,比如只对涉及到更新库存和下订单操作的代码进行上锁)
答:可以使用AOP的环绕操作,将加锁和释放锁的操作放到方法执行前以及事务完成后分别进行,这样的话事务的提交一定是在解锁之前完成。
3.6 所以你是要把所有的业务都走到数据库这一级,等到所有的数据处理完,才允许接收新的请求嘛?
答:
不是的。把所有的业务请求都串行化到数据库处理并等待其完成,会极大地影响系统的并发处理能力和响应速度。我的提议是在可能导致超卖的关键操作上使用锁或其他同步机制,而不是对所有业务操作都使用这种策略。
3.7 如果按照3.5中的方法,并发性会降低
答:但是可以使用多线程嘛
3.8 你程序可以多线程,但是数据库呢?
答:数据库可以做数据隔离,拆分商品,1kw件商品,按照地域进行拆分,并发数会增多,不同地区加不同的行锁,并行数量会增多
4 快手
4.1 你觉得做的最好的需求一个是哪个?详细讲讲
答:做扩容之前,做一份快照,当历史来用,扩容失败可以回滚,扩容成功就做存档了
4.2 代码量由预估的3000行缩减到1000行,最核心的是做了一个什么动作?
答:
4.3 我关心的是怎么想到用这个设计模式呢,之前接触过嘛(考察面试者潜力的问题,最好说自己独立想出来的)
答: 我mentor告诉我的,用什么策略模式比较好,
4.4 设计模式比较熟悉还有哪些?
答:工厂,代理,模板、装饰器
4.5 jdk和相关框架中用了哪些设计模式
答:
代理:aop,rpc的代理
组合模式:mybatis的sql node拼接
模板:mybatis,jdbc
工厂:线程池中的线程工厂创建自定义缓存,spring三级缓存中的第三级缓存也是用到了工厂
4.6 看过这些框架的源码嘛?
答:看过
4.7 什么情况下你一般会看源码?(可能是考察潜力的这么一个过程)
答:通常在以下几种情况下,我会选择深入阅读框架或库的源码:
-
Bug定位:当使用某个框架或库遇到问题,而官方文档或社区没有给出明确答案时,直接查看源码可以帮助快速定位问题所在。
-
性能优化:当需要对系统进行性能优化时,了解底层框架或库是如何工作的,可以帮助找到优化的切入点或者避免不必要的性能开销。
-
深入理解原理:当想要深入了解某个框架或技术的工作原理时,源码是最直接的资料。通过阅读源码,可以更好地理解框架的设计哲学、实现细节和最佳实践。
-
自定义扩展:在某些情况下,框架或库可能没有提供所需的特定功能。通过阅读和了解其源码,可以更方便地进行自定义扩展或修改。
-
学习最佳实践:框架和开源库的源码通常都是由经验丰富的开发者编写的,其代码结构、命名规范和设计模式都是值得学习的最佳实践。
-
评估技术选型:在进行技术选型时,除了参考官方文档和社区反馈外,查看框架或库的源码可以更深入地评估其稳定性、可维护性和扩展性。
-
跟随技术趋势:对于一些新兴的或者前沿的技术框架,了解其源码可以帮助我跟随技术趋势,把握技术发展的方向。
总的来说,阅读源码是一种提高技术深度和广度的有效方法,不仅可以解决实际问题,还可以促进个人技术成长。
5 mini-spring框架
5.1 你当时为什么想做这么一个mini-spring框架呢,既然别人已经写了(答的不好,没有体现出潜力)
我的答案:因为企业问的很多,我觉得自己对spring框架的很多特性不了解,所以就想仿写这么一个,然后面试的时候就能游刃有余
答:制作一个mini-spring框架,即使已经存在完整的Spring框架,主要有以下原因:
-
深入理解原理:通过从头开始构建一个框架,我可以更深入地理解Spring的核心原理和设计思想。这对于学习和掌握Spring的高级特性和最佳实践非常有帮助。
-
技能提升:编写框架需要对Java、设计模式、反射、注解、AOP、IOC等多个领域有深入的了解和实践。这是一个非常好的技能提升机会。
-
实践工程能力:构建框架需要考虑到设计、模块化、扩展性、性能等多个方面。这对于提高工程实践能力和编码习惯都是非常有帮助的。
-
满足好奇心:我一直对框架背后的工作原理和实现细节充满好奇。通过自己动手实现,可以满足我的好奇心,并从中获得乐趣。
-
教学和分享:有时候,完整的Spring框架对于初学者来说可能会显得太过庞大和复杂。一个简化版的mini-spring可以作为一个很好的教学工具,帮助新手快速了解和掌握Spring的核心概念和原理。
-
探索与创新:虽然Spring框架已经非常成熟,但在制作自己的mini版本时,我可以尝试一些新的方法和思路,或者对某些特性进行优化和创新。
总的来说,制作mini-spring框架并不是为了替代已经存在的框架,而是为了学习、实践和探索。通过这个过程,我可以更加深入地理解Spring框架,同时也提高了自己的技术能力和实践经验。
5.2 我很好奇的是,我们那个年代,一般是技术面比较广泛时,然后在向着写一个框架,你为什么是面向面试的呢?(答的不好,没有体现出潜力)
答:因为毕竟高校的教育和当今企业的发展和需要脱节,所以为了面试尽快通过,就像懒加载一样,针对面试问的特别频繁的,就去实现一个,让自己更熟悉
5.3 规避bean的循环依赖,你是怎么实现的
答:我发现一级缓存也可以解决循环依赖,无非是一级单例池这个map的value变成Object,这样的话代理对象和未初始化对象都可以放置,然后
5.4 在真正的生产环境里面,你的一级单例池一般是用于用户线程获取单例对象的是吧,那会存在什么问题呢?
答:对,这里可能会导致未初始化完全的bean提前暴露给用户线程,然后用户线程可能会提前使用并且注入了消息,导致了不一致,所以这个时候就需要三级缓存,做一个隔离。
6 闲聊
6.1 你对于未来工作单位的方向上和期待是什么
答:钱是第一味的,钱给够的话,base地就没限制
6.2 还有其他的考虑嘛?
答:职业发展和晋升
6.3 假如10年后,你希望你是一个什么样的角色?
答:管理者,3年技术leader,5年管理者
6.4 跟你的那个千里IT协会有关系吗?(回答是最好突出一个管理能力和意愿)
答:
(1)有一定关系,毕竟那个时候带过人,知道怎么样才能让一个团队正常工作,
(2)我觉得带别人也是挺好的,管理者发挥的价值其实比程序员更大的,毕竟要带好一个团队,管理得好,能让每个人的效率最大化,这也是自己能力和价值的体现