社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Git

面试吹牛吹过头了,被面试官说让我上传github看看源码,这下老实了,我就做了个半成品,有些功能都没实现,已老实

IT服务圈儿 • 1 月前 • 51 次点击  
来源丨经授权转自 程序媛山楂

作者山楂

不得不说,网上人才是真的多啊,这不,又让我碰到一个“吹牛吹过界”的兄弟。

有个程序员发帖说:“兄弟们,遭了。面试吹牛吹过头了,被面试官说让我上传GitHub看看源码,这下老实了,我就做了个半成品,有些功能都没实现,已老实。”

我看到这儿,差点把手里的泡面喷出来。兄弟你这不就是代码界的“嘴巴超车,手速跟不上”吗?咱写代码写得再慢,也得记得个版本管理,别到时候repo里就俩文件:README.mdtodo.txt

图片

不过我理解,咱程序员有时候一紧张,说话带点缓存是很正常的。但GitHub这玩意儿是硬盘不是嘴,数据会说话啊兄弟!

我建议啊,以后面试前就想好一套说法:比如“这个项目还在refactor阶段,结构我在重构,设计模式我正在考虑要不要用策略+责任链”——听着高端,面试官一般也不敢深问。

实在不行,下次把项目全放私有仓库,然后说:“啊,可能要加我好友才能看。”然后就,再也不加。

面试题:JVM垃圾回收机制

首先,JVM 的垃圾回收,核心目标就一个:自动帮我们处理堆内存中不再使用的对象,释放内存空间,避免内存泄漏和 OOM(OutOfMemoryError)。Java 的 GC 从一开始就是个“后台默默干活”的存在,不过,真想明白它,咱得知道它干活的区域和干活的逻辑。

先说内存划分。JVM 把堆分成了两个主要区域:新生代(Young Generation)和老年代(Old Generation)。新生代里又细分成 Eden 区和两个 Survivor 区(From 和 To)。对象一出生先扔进 Eden 区,经过几次 Minor GC 后还活着的,就慢慢“熬”到老年代。

这时常有人问:GC 是怎么判断一个对象“死了”?这问题问得挺哲学,但 JVM 是靠根可达性(GC Roots)来判断。只要一个对象能从 GC Roots(比如线程栈、本地变量表、静态引用等)一路追踪到,它就还活着;追不到?那就准备被回收。

接下来是大家爱问的回收器。常见组合就是新生代用 ParNew 或 G1 的年轻代部分,老年代用 CMS 或 G1 的老年代部分。面试官一听你说出这些名字,眼睛会亮一下。

比如用 G1 的时候,它不是传统意义上的“代”区分,而是把堆划分成一堆大小相等的 region。新生代、老年代、甚至 humongous object 都是通过 region 组织起来的。G1 的好处是可以做预测性回收,比如你能通过 -XX:MaxGCPauseMillis=200  设置最大 GC 停顿时间,JVM 会尽量控制在这之内。

不过,别的回收器也不能就随便糊弄。比如 CMS(Concurrent Mark Sweep),它虽然是并发回收,但也不是没代价。它要先停顿(Stop-The-World)做一次标记,再在应用运行过程中并发标记和清除,最后还得来一次 Stop-The-World 的重新标记。这也就导致 CMS 容易出现浮动垃圾的问题,因为清除阶段对象还在不断变化。

再说点实战相关的。很多人不理解 Minor GC 和 Full GC 的区别。Minor GC 是回收新生代的,代价比较低,频率高;Full GC 是全场性的,包括老年代和元空间(以前叫永久代),而且会 Stop-The-World,代价大,一旦频繁,就得查内存泄漏或对象“养老”过快的问题了。

来看一段代码直观一点:

public class GCTest {
    public static void  main(String[] args) {
        // 模拟对象快速创建
        for (int i = 0; i 10000; i++) {
            byte[] b = new byte[1024 * 100];  // 每次创建 100KB 对象
        }
    }
}

这段代码会很快触发 Minor GC。你可以加上如下 JVM 参数观察:

-XX:+PrintGCDetails -Xms10m -Xmx10m -Xmn5m

其中 -Xmn5m 是设置新生代为 5MB,基本几轮就能看到 Eden 区满了,然后 Survivor 区搬迁,搬不动的对象晋升到老年代。老年代撑不住了?恭喜你,Full GC 登场!

还得说说对象晋升策略。JVM 不是所有对象都会等着满年龄晋升老年代。如果 Survivor 区装不下,或者大对象直接超过阈值(默认 PretenureSizeThreshold),就可能直接被送进老年代,这也是导致老年代撑不住的常见元凶。

再来点“送命题”:你了解 GC 的三色标记吗?

这其实是 G1、CMS 等并发收集器的底层实现原理,它们用白、灰、黑三种标记来追踪对象引用。白色是“未处理的”,灰色是“待处理的”,黑色是“已处理且安全的”。灰色对象是个“中间态”,它的引用还要进一步扫描。这里就涉及 SATB(Snapshot-At-The-Beginning)算法,专门解决并发标记时对象图变动的问题。

讲这些面试官就知道你不是看了两篇博客就来混面试的,属于真写过代码、真出过 GC 问题、真调过参数的那种选手。

最后说个实话,GC 听起来高深,其实更多是靠你项目里的实际运行情况去调优,而不是死记 JVM 参数。你跑个大数据项目,参数配置跟跑一个电商秒杀系统完全不是一回事,盲目套模板只会出事。

建议大家平时多用 VisualVM、jstat、GCLogAnalyzer 这些工具,把 GC 日志跑一遍分析下,能发现不少平时看不到的细节。别到面试现场才开始“GC 从入门到放弃”,那就晚了。

1、VSCode 数据库客户端扩展神器,不用来回切换 Navicat 了
2、IntelliJ IDEA 2025.1 正式发布,新功能太爽了。。
3、手机新规将施行:必须贴电池能效标签+至少能用7年!
4、1200 人 Star!500 块自己搞 1 个低成本无人机。
5、中国最难入的IT公司。。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/181632
 
51 次点击