Appearance
语言基础共性题
无论 Java、Go、C++ 还是前端语言,面试官都喜欢问这类"跨语言共性题",考察的是你对语言本质的理解,而不是某个 API 的用法。
Q1: 值传递和引用传递有什么区别? 「🟢 校招/初级」
考察点:参数传递机制、内存模型的基本认知。
参考答案:
- 值传递:把实参的副本传给形参,函数内修改形参不影响实参。基本数据类型几乎都是值传递。
- 引用传递:把实参本身的"地址/引用"传过去,函数内可以通过它修改原对象。
- 常见误区:Java 只有值传递——对象传的是"引用的副本",所以能改对象内部字段,但不能让实参指向新对象;Go 同理,想修改指针本身要传
**T。
追问延伸:
- Java 里
String传参后为什么"看起来"没被修改?(不可变对象) - Go 的 slice 传参为什么有时修改生效、有时不生效?(扩容时底层数组被替换)
Q2: 深拷贝和浅拷贝的区别? 「🟢 校招/初级」
考察点:对象内存结构、引用语义。
参考答案:
- 浅拷贝:只复制对象本身和其中的基本类型字段,引用类型字段仍然指向同一个对象。
- 深拷贝:递归复制所有引用字段,新旧对象完全独立,改一个不影响另一个。
- 实现方式:序列化反序列化、手动递归克隆、语言提供的深拷贝工具(如 JS 的
structuredClone)。
追问延伸:
- 为什么大对象要慎用深拷贝?(内存与时间开销)
- 单例模式下的对象需要拷贝吗?
Q3: 栈内存和堆内存的区别? 「🟢 校招/初级」
考察点:内存管理基础,是后续 GC、逃逸分析话题的铺垫。
参考答案:
- 栈:随函数调用自动分配释放,速度快,容量小,存局部变量、函数参数、返回地址。
- 堆:由程序员或 GC 管理,容量大,存动态分配的对象;分配释放开销大,可能产生碎片。
- 带 GC 的语言里,编译器会做逃逸分析:没逃逸出函数的对象可以分配在栈上。
追问延伸:
- Go 里什么样的变量会逃逸到堆上?
- 递归太深为什么会栈溢出?
Q4: 什么是异常?怎么设计异常体系? 「🟡 中级」
考察点:错误处理观念,区分"异常"与"错误"。
参考答案:
- 异常是程序运行中的非正常事件,用于把"出错信息"从业务代码中分离出来。
- 一般分为受检异常(必须显式处理,如 Java checked exception)和非受检异常(运行时错误,如空指针)。
- 设计原则:异常只用于真正的异常情况,不用来做流程控制;分层传递、统一处理;日志记录原始异常链,避免吞异常。
- Go 的反例:用多返回值
error显式处理,强迫调用方每次判断,避免异常被静默忽略。
追问延伸:
try-catch会影响性能吗?(创建异常对象取堆栈有开销,捕获本身开销小)- 为什么不建议用异常做循环退出条件?
Q5: 解释一下强类型和弱类型、静态类型和动态类型 「🟢 校招/初级」
考察点:类型系统的基本概念,能区分两个正交的维度。
参考答案:
- 静态/动态类型:类型检查发生在编译期还是运行期。Java、Go、TS 是静态;Python、JS 是动态。
- 强/弱类型:是否允许隐式类型转换。Python 是强类型(
"1"+2报错);C、JS 是弱类型(允许隐式转换,"1"+2得"12")。 - 两个维度正交:Java 是静态强类型,JS 是动态弱类型。
追问延伸:
- TypeScript 对 JS 的类型增强是怎么做到零运行时开销的?
- 为什么弱类型语言更容易出隐蔽 bug?
Q6: 什么是编译型和解释型语言? 「🟢 校招/初级」
考察点:程序执行模型,顺带考察对虚拟机、JIT 的了解。
参考答案:
- 编译型:源码一次性编译成机器码再执行,如 C、Go;启动快、执行效率高。
- 解释型:边解释边执行,如 Python;开发灵活、跨平台依赖解释器。
- 现代语言多为混合:Java/Go 编译为中间形态再由虚拟机/运行时执行;Java 还有 JIT 把热点代码即时编译成机器码。
追问延伸:
- JVM 的 JIT 编译器什么时候介入?
- Go 编译成机器码,为什么还需要运行时(GC、调度器)?