如我之前所说,11 月上旬到中旬,是开奖的高峰期,这不,荣耀也陆续开了,base 地有南京、深圳,以及西安。
我这里也整理了一些开奖的情况,给大家做个参考。
- 硕士 985,算法开到 27k,白菜不太满意,南京地区
- 硕士双一流,测试工程师,开到 24k,一周考虑时间,地区是深圳
- Java 开发,17*16,HR 说月末周六加班,双倍工资,深圳地区,公积金是 5%
- 双 9,软测,给到(20+6)*12+8w,6 是绩效,8 是年终,base 深圳
- 本科 985,17+5,14或者 16 薪,也是深圳,通软
- 西电本硕,通用软件开发,开了 (19+5)×12,10-31 的 14.40 开奖,9.29 二面,西安地区
整体上来说,荣耀和去年的情况也是差不多,没有变化特别大,星球里之前也有小伙伴拿到荣耀的 offer。
像荣耀和华为,其实比较适合那些学历很不错,但技术实力稍微有点欠缺的同学,因为从荣耀的面经来看,大部门都比较友好,不会往高并发高可用高性能,微服务分布式上去卷。
只要面试没有出现大的方向问题,还是能泡出来的,接下来,我们就以《Java 面试指南》中收录的同学 4 面经来看看,荣耀的面试官都喜欢问哪些问题,26 届的小伙伴可以做个参考。
荣耀同学 4 面经
项目怎么做的
由于平常热爱技术分享,于是就萌生一个大胆的想法,做一个比 CSDN、掘金、知乎更厉害的内容社区,起名叫技术派。
技术派里面用到的都是互联网当下最流行的技术架构,骨架是通过 Spring Boot+Mybatis-Plus 搭建的,并且是前后端分离的,admin 端用的是 React + TypeScript,其中还用到了数据库 MySQL、缓存中间件 Redis、搜索引擎 ElasticSearch、nosql 数据库 MongoDB、容器化技术 Docker、消息中间件 RabbitMQ、权限安全框架 SpringSecurity、日志框架 Logback、 接口文档 Knife4j、及时消息通信 WebSocket 等技术栈,并且对接了当前最火热的 AI 大模型 OpenAI 和讯飞星火 API,项目支持一键启动和部署,这个过程让我的技术得到了极大的提升。
Redis和MySQL的区别?
- Redis:数据存储在内存中的 NoSQL 数据库,读写性能非常好,是互联网技术领域中使用最广泛的缓存中间件。
- MySQL:数据存储在硬盘中的关系型数据库,适用于需要事务支持和复杂查询的场景。
有没遇到内存泄露,溢出的情况,怎么发生和处理的?
有,内存溢出,也就是 Out of Memory,是指当程序请求分配内存时,由于没有足够的内存空间满足其需求,从而触发的错误。
当时在做技术派的时候,由于上传的文件过大,没有正确处理,导致一下子撑爆了内存,程序直接崩溃了。
当发生 OOM 时,可以导出堆转储(Heap Dump)文件进行分析。如果 JVM 还在运行,可以使用 jmap 命令手动生成 Heap Dump 文件:
jmap -dump:format=b,file=heap.hprof <pid>
生成 Heap Dump 文件后,可以使用 MAT、JProfiler 等工具进行分析,查看内存中的对象占用情况,找到内存泄漏的原因。
如果生产环境的内存还有很多空余,可以适当增大堆内存大小,例如 -Xmx4g
参数。
或者检查代码中是否存在内存泄漏,如未关闭的资源、长生命周期的对象等。
之后,我会在本地进行压力测试,模拟高负载情况下的内存表现,确保修改有效,且没有引入新的问题。
对垃圾回收的理解?
垃圾回收(Garbage Collection,GC)就是对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收。
JVM 在做 GC 之前,会先搞清楚什么是垃圾,什么不是垃圾,通常会通过可达性分析算法来判断对象是否存活。
在确定了哪些垃圾可以被回收后,垃圾收集器(如 CMS、G1、ZGC)要做的事情就是进行垃圾回收,可以采用标记清除算法、复制算法、标记整理算法、分代收集算法等。
技术派项目使用的 JDK 8,所以默认采用的是 CMS 垃圾收集器。
说一些你自己熟悉的技术(说了AQS,锁)
AQS,也就是抽象队列同步器,由 Doug Lea 设计,是 Java 并发包java.util.concurrent
的核心框架类,许多同步类的实现都依赖于它,如 ReentrantLock、Semaphore、CountDownLatch 等。
AQS 的思想是,如果被请求的共享资源空闲,则当前线程能够成功获取资源;否则,它将进入一个等待队列,当有其他线程释放资源时,系统会挑选等待队列中的一个线程,赋予其资源。
整个过程通过维护一个 int 类型的状态和一个先进先出(FIFO)的队列,来实现对共享资源的管理。
①、同步状态 state 由 volatile 修饰,保证了多线程之间的可见性;
private volatile int state;
②、同步队列是通过内部定义的 Node 类来实现的,每个 Node 包含了等待状态、前后节点、线程的引用等。
static final class Node {
static final int CANCELLED = 1;
static final int SIGNAL = -1;
static final int CONDITION = -2;
static final int PROPAGATE = -3;
volatile Node prev;
volatile Node next;
volatile Thread thread;
}
AQS 支持两种同步方式:
- 独占模式:这种方式下,每次只能有一个线程持有锁,例如 ReentrantLock。
- 共享模式:这种方式下,多个线程可以同时获取锁,例如 Semaphore 和 CountDownLatch。
子类可以通过继承 AQS 并实现它的方法来管理同步状态,这些方法包括:
tryAcquire
:独占方式尝试获取资源,成功则返回 true,失败则返回 false;tryRelease
:独占方式尝试释放资源;tryAcquireShared(int arg)
:共享方式尝试获取资源;tryReleaseShared(int arg)
:共享方式尝试释放资源;isHeldExclusively()
:该线程是否正在独占资源。
如果共享资源被占用,需要一种特定的阻塞等待唤醒机制来保证锁的分配,AQS 会将竞争共享资源失败的线程添加到一个 CLH 队列中。
在 CLH 锁中,当一个线程尝试获取锁并失败时,它会将自己添加到队列的尾部并自旋,等待前一个节点的线程释放锁。
提到调参,不同方向都涉及到调参,问怎么能获得最优参数呢,思路是什么样的
确实,比如说数据库连接池的参数优化、Redis 缓存配置、JVM 运行参数,以及 ES 集群配置等。
要想获得最优参数,我觉得首先要明确调优的目标,是降低响应时间、提高吞吐量,还是减少内存占用?
比如在 JVM 调优中,如果目标是减少 GC 停顿,那么关注点会在垃圾收集器的选择和堆大小配置上。
然后在调参时,每次尽量只调整一个或者少量参数,确保参数对系统性能的确产生了影响。
比如说针对 Redis 缓存,可以先调节最大内存使用限制,再逐步优化缓存淘汰策略,观察每个参数调整的效果。
常用的调优方法包括对参数进行穷举,随机组合一些参数等,最好有一些理论基础,比如说在进行线程池的核心线程数设置,要先确认是 CPU 密集型任务还是 IO 密集型,
对于 CPU 密集型任务,目标是尽量减少线程上下文切换,以优化 CPU 使用率。一般来说,核心线程数设置为处理器的核心数或核心数加一(以备不时之需,如某些线程因等待系统资源而阻塞时)是较理想的选择。
对于 IO 密集型任务,由于线程经常处于等待状态(等待 IO 操作完成),可以设置更多的线程来提高并发性(比如说 2 倍),从而增加 CPU 利用率。
最后,在调参结束后,要通过压力测试验证是否达到预期目标。可以使用 JMeter 对接口进行压测,观察参数调整后的性能改进。
接触过那些语言?
大一上先学习的 C 语言,大一下半学期开始学习 Java,中间还学过一些 Python 和 JavaScript,但整体的感受上来说还是最喜欢 Java。
因为它可以做的事情太多了,既可以用它来爬一些数据做测试,还可以用它来写 Web 后端服务,就连一些轮子也可以用它来造,比如说我之前写过一个 MYDB 的轮子,就是用的 Java。
内容来源
- 星球嘉宾三分恶的面渣逆袭:https://javabetter.cn/sidebar/sanfene/nixi.html
- 二哥的 Java 进阶之路(GitHub 已有 12000+star):https://javabetter.cn