likes
comments
collection
share

去东方不败公司面试,被惊艳到了。

作者站长头像
站长
· 阅读数 47

大家好,我是小二啊。

昨天去东方不败公司面试,真的被惊艳到了。好家伙,是真正的 BOSS 下场面试,那声音、那面容,让我无法自拔、欲仙欲死。

去东方不败公司面试,被惊艳到了。

听说过东方不败厉害,但没想到这么厉害,他对自己的武功和爱情都有着独特的理解和坚持。

小时候就刷过央视版的笑傲江湖,虽然东方不败露脸的时间很短,但却印象深刻。前段时间又刷了林青霞版的《笑傲江湖之东方不败②》,当真是又一次被那气质精准拿捏。

东方不败虽然已经退居公司幕后,公司的日常管理都交给了男宠杨莲亭,但公司的实际掌控权还是在他手中,并且分得清好坏。

这次去东方不败的公司日月神教面试,绝不是想修炼葵花宝典,而是希望一睹他的风采和神情���真心话🤣)。从他问我的问题也能看得出来,东方不败对技术还是有追求的,不信来一睹为快。

东方不败公司面经

项目里遇到了什么难题,怎么解决的

在技术派这个项目当中,遇到了蛮多有挑战的任务。

比如说 MySQL 的库表自动初始化,用户在启动项目前不需要手动导入 SQL 文件,只需要在 application.yml 中配置好 MySQL 的用户名和密码,run 以下 main 类,就自动完成了。这个是通过 Liquibase 实现的。

去东方不败公司面试,被惊艳到了。

再比如说技术派是一个前后端分离项目,admin 端请求后端 API 接口时会遇到跨域问题,这个可以通过 Node 代理或者 Nginx 设置同源策略解决。

再比如说用户点赞、收藏文章的时候,可以通过 RabbitMQ 的发布/订阅模式来提高异步效率,保证用户的操作能够得到及时反馈。

再比如说为了满足社区在高并发场景下业务 ID 的唯一性和可追溯性,我们实现了一套基于雪花算法(Snowflake)的 ID 生成方案,进一步降低了 ID 生成的延迟。

还有我们通过 Redis 实现了计数统计和用户活跃度排行,并通过先写 MySQL,再删除 Redis 的方案来保证高并发场景下的缓存一致性。

还有在对接讯飞星火、OpenAI 等大模型平台的时候,为了提高代码的复用性和可扩展性,我们采用了策略模式+抽象工厂的模式来实现。

你用过消息队列吗,消息队列实现的是什么,还有什么消息队列

在技术派项目中,通过 RabbitMQ 实现了消息异步解耦,当用户订阅、点赞、评论时,就会触发消息通知,如果当用户操作时,消息同步发送,当消息出现异常时,会影响主流程,或者当消息过多时,也会有影响服务的性能,所以需要对消息进行异步解耦。

消息队列(Message Queue, MQ)是一种非常重要的中间件技术,广泛应用于分布式系统中,以提高系统的可用性、解耦能力和异步通信效率。

除了使用 RabbitMQ,我还用到了 Kafka,最初由 Linkedin 公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统。

分布式锁怎么实现的

Redis 实现分布式锁的本质,就是在 Redis 里面占一个“茅坑”,当别的客户端也来占坑时,发现已经有客户端蹲在那里了,就只好放弃或者稍后再试。

可以使用 Redis 的 SET 命令实现分布式锁。SET 命令支持设置键值对的同时添加过期时间,这样可以防止死锁的发生。

去东方不败公司面试,被惊艳到了。

SET key value NX PX 30000
  • key 是锁名。
  • value 是锁的持有者标识,可以使用 UUID 作为 value。
  • NX 只在键不存在时设置。
  • PX 30000:设置键的过期时间为 30 秒(防止死锁)。

上面这段命令其实是 setnx 和 expire 组合在一起的原子命令,算是比较完善的一个分布式锁了。

介绍一些线程与进程的区别

进程说简单点就是我们在电脑上启动的一个个应用,比如我们启动一个浏览器,就会启动了一个浏览器进程。进程是操作系统资源分配的最小单位,它包括了程序、数据和进程控制块等。

线程说简单点就是我们在 Java 程序中启动的一个 main 线程,一个进程至少会有一个线程。当然了,我们也可以启动多个线程,比如说一个线程进行 IO 读写,一个线程进行加减乘除计算,这样就可以充分发挥多核 CPU 的优势,因为 IO 读写相对 CPU 计算来说慢得多。线程是 CPU 分配资源的基本单位。

去东方不败公司面试,被惊艳到了。

synchronized和volatile的区别

volatile 关键字用于修饰变量,确保该变量的更新操作对所有线程是可见的,即一旦某个线程修改了 volatile 变量,其他线程会立即看到最新的值。

synchronized 关键字用于修饰方法或代码块,确保同一时刻只有一个线程能够执行该方法或代码块,从而实现互斥访问。

synchronized可重入锁怎么实现的

可重入意味着同一个线程可以多次获得同一个锁,而不会被阻塞。具体来说,如果一个线程已经持有某个锁,那么它可以再次进入该锁保护的代码块或方法,而不会被阻塞。

synchronized 之所以支持可重入,是因为 Java 的对象头包含了一个 Mark Word,用于存储对象的状态,包括锁信息。

当一个线程获取对象锁时,JVM 会将该线程的 ID 写入 Mark Word,并将锁计数器设为 1。

如果一个线程尝试再次获取已经持有的锁,JVM 会检查 Mark Word 中的线程 ID。如果 ID 匹配,表示的是同一个线程,锁计数器递增。

当线程退出同步块时,锁计数器递减。如果计数器值为零,JVM 将锁标记为未持有状态,并清除线程 ID 信息。

JVM内存区域介绍一下

JVM 的内存区域,有时叫 JVM 的内存结构,有时也叫 JVM 运行时数据区,按照 Java 的虚拟机规范,可以细分为程序计数器虚拟机栈本地方法栈方法区等。

去东方不败公司面试,被惊艳到了。

其中方法区是线程共享的,虚拟机栈本地方法栈程序计数器是线程私有的。

JVM垃圾回收介绍一下

垃圾回收(Garbage Collection,GC),顾名思义就是释放垃圾占用的空间,防止内存爆掉。有效的使用可以使用的内存,对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收。

JVM 在做垃圾回收之前,需要先搞清楚什么是垃圾,什么不是垃圾,那么就需要一种垃圾判断算法,通常有引用计数算法、可达性分析算法。

去东方不败公司面试,被惊艳到了。

在确定了哪些垃圾可以被回收后,垃圾收集器要做的事情就是进行垃圾回收,如何高效地进行垃圾回收呢?

可以采用标记清除算法、复制算法、标记整理算法、���代收集算法等。

JVM 提供了多种垃圾回收器,不同的垃圾回收器适用于不同的场景和需求,包括 CMS GC、G1 GC、ZGC 等。

CMS垃圾收集器和G1垃圾收集器什么区别

CMS 是第一个关注 GC 停顿时间(STW 的时间)的垃圾收集器,JDK 1.5 时引入,JDK9 被标记弃用,JDK14 被移除。

G1(Garbage-First Garbage Collector)在 JDK 1.7 时引入,在 JDK 9 时取代 CMS 成为了默认的垃圾收集器。

去东方不败公司面试,被惊艳到了。

CMS 适用于对延迟敏感的应用场景,主要目标是减少停顿时间,但容易产生内存碎片。G1 则提供了更好的停顿时间预测和内存压缩能力,适用于大内存和多核处理器环境。

HTTP和HTTPS什么区别,HTTPS的安全怎么实现的

  1. HTTPS 是 HTTP 的增强版,在 HTTP 的基础上加入了 SSL/TLS 协议,确保数据在传输过程中是加密的。SSL/TLS 需要向 CA(证书权威机构)申请数字证书,用于验证服务器的身份。
  2. HTTP 的默认端⼝号是 80,URL 以http://开头;HTTPS 的默认端⼝号是 443,URL 以https://开头。

HTTPS的安全怎么实现的

使用 HTTPS 主要是为了解决 HTTP 传输过程中的一些安全问题,因为 HTTP 是明文传输,所以 HTTPS 在 HTTP 的基础上加入了 SSL/TLS 协议。

去东方不败公司面试,被惊艳到了。

SSL(安全套接字)/TLS(传输层安全)协议可以用来加密通信内容,保证通信过程中的数据不被窃取和篡改。

MySQL的索引数据结构是什么,主键索引和非主键索引在数据结构上有什么区别

MySQL 的默认存储引擎是 InnoDB,其索引实现采用 B+ 树结构。

在 InnoDB 存储引擎中,主键就是聚簇索引。聚簇索引不是一种新的索引,而是一种数据存储方式

去东方不败公司面试,被惊艳到了。

在聚簇索引中,表中的行是按照键值(索引)的顺序存储的。这意味着表中的实际数据行和键值之间存在物理排序的关系。因此,每个表只能有一个聚簇索引。

在非聚簇索引中,索引和数据是分开存储的,索引中的键值指向数据的实际存储位置。因此,非聚簇索引也被称为二级索引或辅助索引或非主键索引。表可以有多个非聚簇索引。

这意味着,当使用非聚簇索引检索数据时,数据库首先在索引中查找,然后通过索引中的指针去访问表中实际的数据行,这个过程称为“回表”(Bookmark Lookup)。

MySQL怎么分析SQL的性能(expain 查询慢sql)?慢sql日志怎么开启?expain的type字段中,什么样的需要优化

explain 是 MySQL 提供的一个用于查看查询执行计划的工具,可以帮助我们分析查询语句的性能瓶颈,找出慢 SQL 的原因。

使用方式也非常简单,在 select 语句前加上 explain 关键字就可以了。

explain select * from students where id =9

慢sql日志怎么开启?

慢 SQL 日志的开启方式有多种,比如说直接编辑 MySQL 的配置文件 my.cnf 或 my.ini,设置 slow_query_log 参数为 1,设置 slow_query_log_file 参数为慢查询日志的路径,设置 long_query_time 参数为慢查询的时间阈值。

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2  # 记录执行时间超过2秒的查询

然后重启 MySQL 服务就好了,也可以通过 set global 命令动态设置。

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
SET GLOBAL long_query_time = 2;

expain的type字段中,什么样的需要优化

type 列:表示 MySQL 在表中找到所需行的方式,性能从最优到最差分别为:system > const > eq_ref > ref > range > index > ALL。

  • system,表只有一行,一般是系统表,往往不需要进行磁盘 IO,速度非常快
  • const、eq_ref、ref:这些类型表示 MySQL 可以使用索引来查找单个行,其中 const 是最优的,表示查询最多返回一行。
  • range:只检索给定范围的行,使用索引来检索。在where语句中使用 bettween...and<><=in 等条件查询 type 都是 range
  • index:遍历索引树读取。
  • ALL:全表扫描,效率最低,最好优化。

Spring AOP基于什么实现(动态代理)?那SpringAOP如何实现动态代理

Spring 的 AOP 是通过动态代理来实现的,动态代理主要有两种方式:JDK 动态代理和 CGLIB 代理。

①、JDK 动态代理是基于接口的代理,只能代理实现了接口的类。使用 JDK 动态代理时,Spring AOP 会创建一个代理对象,该代理对象实现了目标对象所实现的接口,并在方法调用前后插入横切逻辑。

优点:只需依赖 JDK 自带的 java.lang.reflect.Proxy 类,不需要额外的库;缺点:只能代理接口,不能代理类本身。

②、CGLIB 动态代理是基于继承的代理,可以代理没有实现接口的类。使用 CGLIB 动态代理时,Spring AOP 会生成目标类的子类,并在方法调用前后插入横切逻辑。

去东方不败公司面试,被惊艳到了。

优点:可以代理没有实现接口的类,灵活性更高;缺点:需要依赖 CGLIB 库,创建代理对象的开销相对较大。

面试后续

这次东方不败公司的面试题难度不算小,从 Java 后端四大件问到计算机网络,基本上问了个遍,我也如愿拿到了 offer。

甚至东方不败看我天赋不错,想把葵花宝典传授于我,说一旦我修炼了神功,往后跳槽可就容易多了,吊打其他公司的面试官不在话下哦

但被我义正言辞的拒绝了,毕竟我还年轻,我真正想学的还是风清扬的独孤九剑,而不是绣花针。。但我没敢说出来,怕东方不败一怒之下废了我。。🤣

转载自:https://juejin.cn/post/7383657525687861302
评论
请登录