禾迈电力电子成都线下一面面经
- 轮次
- 一面
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 自我介绍
- Java 协程用了栈吗?
- Java 底层调用 C++ 和系统命令这些了解吗?
- MySQL 版本用的什么?
- 有没有什么数据库设计要违背三大范式的场景?
- 设备 MAC 地址可以改写吗?
- 一台电脑能有多个 IP、多个 MAC 吗?
- Redis 的 ZSET 里的 score 在内存里是怎么存储的,会不会越界?
- SSE 长连接,底层也是长连接吗?为什么?
- AARP 协议了解吗?
- 局域网内一台电脑怎么知道另一台电脑的 IP?
- 反问:只有一面,两周给结果,强度 8 小时工作,偶尔加班
《参考解析》
- Java 虚拟线程用不用栈:虚拟线程(JDK 21 正式)不是没有栈,而是把栈帧存在堆上的
StackChunk对象里,挂起时整块搬到堆、恢复时再拷回载体线程的栈。所以它可以是「廉价的、可增长收缩的」栈,不像平台线程那样一创建就占固定的 1MB 左右栈空间。这也是它能开出百万级数量的原因——真正的开销从线程栈转移到了堆内存。 - JNI 与系统命令调用:
System.loadLibrary+native方法走 JNI,代价是跨语言边界、不能内联优化、出错就是 JVM 崩溃;JDK 22 起有 FFM API(java.lang.foreign,JDK 22 预览、JDK 24 正式)作为更安全的替代。调系统命令一般用ProcessBuilder起子进程,注意要读干净 stdout / stderr 再waitFor,否则管道缓冲区满会直接卡死。 - 违背三大范式的场景:范式是为了减少冗余和更新异常,但性能和可查性有时更重要。典型的有:频繁多表 join 的报表场景做冗余字段或宽表;订单表把商品名称、下单时的价格快照冗余进去(历史数据不能随商品改动而变化,这属于业务上的必须);计数器、排行榜这类聚合值单独存一份避免每次实时聚合;还有分库分表后为了减少跨库 join 而故意反范式。
- MAC 地址能不能改:物理网卡出厂烧录的 MAC 是固化的,但操作系统层面可以改——Linux 用
ip link set dev eth0 address ...,Windows 在网卡属性里改,改的是驱动读到的值。所以「MAC 唯一标识设备」并不可靠,做授权或风控时不能只依赖它。 - 一个设备多个 IP / 多个 MAC:可以。多个网卡(有线 + 无线 + 虚拟网卡 / Docker 网桥)各自有 MAC 和 IP;同一张网卡也能绑多个 IP(别名或 secondary address),IPv4 和 IPv6 并存更是常态。容器和虚拟化场景下 MAC 由虚拟网桥分配,和物理网卡没有关系。
- Redis ZSet 的 score 存储与越界:底层是 skiplist + dict,score 存成 double(8 字节 IEEE 754)。
+inf和-inf都是合法的 score,但整数运算超出 2^53 之后就丢精度——用毫秒时间戳当 score 没问题(约 1.7×10^12),但如果拿纳秒级时间戳或雪花 ID 直接当 score,就会因为精度丢失出现排序错乱。 - SSE 与长连接:SSE(Server-Sent Events)本身就是一个不分块关闭的 HTTP 响应,服务端用
Content-Type: text/event-stream保持连接持续写数据。所以它确实是长连接,但只是「服务端到客户端」的单向长连接,客户端要发消息得另开一个请求。它和 WebSocket 的区别就在这里:WebSocket 是全双工、需要协议升级握手,SSE 只是普通 HTTP 响应,天然能过大部分代理和网关(代价是要处理中间层的空闲超时和重连,Last-Event-ID就是为此设计的)。 - ARP 与局域网内发现对方 IP:ARP 的作用是把 IP 解析成 MAC——广播「谁是这个 IP」的请求,对应主机单播回应自己的 MAC,结果缓存在 ARP 表里。反过来的「知道 MAC 找 IP」不是 ARP 干的,通常靠 RARP / DHCP 记录,或者直接扫网段(ARP 扫描工具会给每个地址发请求,谁回应就知道谁在线)。注意 ARP 没有认证,ARP 欺骗就是利用这一点冒充网关。