想去国企了,学 Java 还是 C++?

共 11235字,需浏览 23分钟

 ·

2024-05-29 17:06

图解学习网站:https://xiaolincoding.com

之前分享过一些国企的面经:不想卷了,冲国企去了!!,有不少同学咨询问我,想去国企躺平,学 Java 还是 C++?

很多国企比如银行、证券在招聘IT岗的时候会要求你会一门大语言(比如Java、python、C++)。

其中python一般应用于算法、数据分析与处理等岗位,Java一般应用于服务端开发,C++一般应用于嵌入式开发等岗位。

但是目前高校的教学实际上是与实际生产脱离开的,现实生产环境可能已经开始敏捷开发了,而学校里还在对着课本教 C 语言程序设计。

在这里我不否认底层知识,比如操作系统、编译原理等课程的用处。但是从招聘角度来说,一切都是从市场需求出发,有需求才有岗位。

所以回到国企IT岗的招聘需求上来,Java后端开发需求量巨大,很多国企里的员工入职培训也是学的Java。

如果你没有任何工程化基础,我建议你将Java作为自己首门大语言

之前朋友校招的时候,由于非科班出身,项目专注于医疗视觉算法的研究,而忽视了工程化的一些东西,导致招聘的时候连mysql、计算机网络一些基础知识都不清楚。

还好当时发现的时间比较早,后续花了 3 个月的时间将Java基础补上来了,最终拿到的offer有大厂、国企等十几家企业。

网上关于 Java 的教程太多了,很多资料一上来就会提出一些非常抽象的名词,让新手不好理解。其实这些抽象的名字,其本质都非常简单。

为啥要用抽象的名字呢?是要提升架构师的逼格,让别人觉得他很厉害,这和写论文一个道理。

所以,在这个Java学习路线中(初学者可搭配HeadFirstJava这一本书),我将由浅入深地介绍如何学习Java,分为基础篇和应用篇

希望读者带着为什么的态度,而不是就这样死记硬背的想法来阅读它。如果觉得有用可以点个赞哦

基础篇

一、熟悉一种文本编辑器

比如 Vim, Emacs, VSCode, GEdit, Kate, TextMate 等。知道哪些是开源的,哪些是闭源的,哪些要收费。

二、安装 OpenJDK

建议用你的 Linux 发行版自带的软件包管理器安装 OpenJDK,比如 Ubuntu 用 apt-get,Fedora 用 dnf,ArchLinux 用 pacman,Mac 用户可以用 Homebrew,Windows 用户就用 Adoptium Eclipse Temurin 提供的安装包吧。

这个过程中可能需要读发行版特定的文档,比如 ArchLinux 的 wiki、Fedora 的使用手册、Ubnutu 官网上的文档等。

三、Javac写一个Hello world 程序

用命令行工具 Javac 编译,再用 Java 命令运行这个程序。

过程中熟悉源代码、字节码、虚拟机这些东西,以及 Java 的包(package)对.class 文件所在的路径的影响。

如果这两个命令行工具使用熟练了,可以开始选一个喜欢的集成开发环境,比如 IntelliJ IDEA、Eclipse 等。

四、 学习 Java 的面向过程编程

包括基本数据结构、表达式、语句、控制流、函数调用。这个过程中了解一下新版 Java 的特性,比如 var 关键字。如果你的教程没有提到 var 关键字,可能太旧了。

五. 学习 Java 的面向对象编程

包括类、引用类型和值类型的区别、成员、方法、访问控制、继承、多态、接口、接口实现。

  1. 学习一下面向对象的基本思想,即对象、消息、封装、继承、多态等,这些通用的内容不是 Java 特有的。
  2. 这时候应该已经涉及了 Java 的垃圾回收。要留意即使有垃圾回收的情况下也会发生的内存泄露(如自己设计数组容器,元素是引用,逻辑上删除了元素,但并没有清成 null)。
  3. 也要注意垃圾回收只能回收内存中的对象,除了内存以外,其它资源不能依靠垃圾回收来关闭。比如,文件、管道、Socket、数据库连接等,垃圾回收是不会帮你关闭的。
  4. 你应该用 try-with-resource 语句来自动关闭上述资源,比如 InputStream、OutputStream、Scanner 等。如果你的教材没有提到 try-with-resource 语句,你的教材就太老了。
  5. finanlize 方法已经“deprecated for removal”了。不要再用了。有兴趣的可以了解一下 Cleaner。
  6. 学习 Java 的异常处理,但更重要的是学习什么时候用特殊返回值而不使用异常,什么时候应该抛出异常而不处理异常,知道什么是 pokemon catch 及其危害,了解为什么 Java 的 checked exception 是一个糟糕的特性。
  7. 你大多数时候应该使用 try-with-resource 语句,偶尔使用 try-finally,很少需要使用 try-catch。

六、 熟悉 Java 常用的数据结构

如基本的数组类型,以及泛型容器(Java.util.*),尤其是 Java.util.List接口和 Java.util.ArrayList实现;以及 Java.util.Map<T,U>接口和 Java.util.HashMap<T,U>实现。(Java1.5 以前的没有泛型参数的就不用碰了)同时留意一下基本类型 int, double 等和装箱类型 Integer 和 Double 的区别,以及它们是如何自动转换的。

七、 熟悉 Java 标准库里的各种工具

包括日期时间、字符串格式化、IO 等。知道垃圾回收器不会帮你关掉文件。文件要用 try-with-resource 来保证它及时关闭。或者自己写 try-finally 语句,在 finally 子句中 close()。

八、 学习一下 Java 的命名习惯,以及 JavaBeans 的常规

知道为什么 getter/setter 比直接操作成员变量好。按这种方式给 Java 的变量、方法命名。同时看看你的 IDE 能不能自动帮你生成 getter 和 setter。

九、使用一个第三方的库(比如 Apache Commons Lang 通用工具库)

让你的程序依赖于它的二进制 jar 包(而不是直接拷贝源代码),用命令行编译、运行(注意 classpath 等);也熟悉一下如何用你的集成开发环境添加第三方依赖。感受一下手动管理依赖关系的麻烦。

十、 学习 Maven 和 gradle 的使用

试着让 Maven 帮你解决依赖关系。再试试用 Maven 打包发布。

  1. 如果你使用 IDEA,试着用它直接打开一个 Maven 或者 gradle 工程。
  2. 如果你使用 Eclipse,试试用 Maven 或者 gradle 生成一个 Eclipse 工程。
  3. 学习一下 Ant 的用法,并用Ivy 从 Maven 的仓库里下载软件包,解决依赖关系。

十一、 学习软件测试

以及 JUnit 的使用,以及怎么在 IDE 中使用 JUnit。有空看一下 coverage 工具。

应用篇

接下来就看具体要做哪方面的应用了,看需求。比如(下面的没有顺序)

一、调试和辅助工具

  • 学习一下你的集成开发环境提供的调试工具,加一些断点试试
  • 试试用 jconsole 或者 VisualVM 监控另一个 jvm 的状态。
  • 用 profiling 工具寻找程序中慢的地方。Eclipse 有 profiling 工具。VisualVM 也有这样的功能。(如果不介意使用闭源软件的话,也试试 JProfiler 和 YourKit)
  • 有的 JVM 允许在运行时更新代码。Eclipse 可以和某些 JVM 集成。这样你可以频繁修改代码而不用频繁重启 JVM。对于某些“重型”工程很有用。(如果不介意使用闭源软件的话,也试试 jRebel)

二、多线程

先读 Oracle 的 Java Tutorial 里的这一章,

请自始至终关注“happens-before“这个词!

请自始至终关注“happens-before“这个词!

请自始至终关注“happens-before“这个词!

重要的话要说三遍!学完以后应该可以写出正确的并发程序了。

  • 了解多核处理器、缓存、内存的关系,以及 CPU 内部的内存读写指令的重排序等细节,体会一下为什么多线程编程这么难。
  • 学习 Java 的多线程编程接口,主要是 lock、condition 的用法
  • Java每个对象都可以用 synchronized 语句同步,有 wait, notify 方法,但这套机制有缺陷。
  • 看看 Java.util.concurrent.lock 里的 Lock 和 Condition 接口,看它们是怎么解决这些缺陷的。
  • 学完之后,学学用 Future 和 Promise 来同步,而不是手动用 lock 和 condition。
  • 还有 semaphore、cyclic barrier、count-down latch、phaser 等高级同步工具,或许可以少重新发明一些轮子。
  • 还有 BlockingQueue
  • 学习一下如何让线程停下来,以及为什么要频繁确认 isInterrupted()而不要用 Thread.stop()(看 Java API 里 Thread.stop()的文档)。
  • 学习一下用 Runnable 来封装“任务”而不是“线程”,并用 Java 自带的 ThreadPoolExecuter、ForkJoinPool 等工具帮你管理线程。
  • 应该已经留意到 Java.util 里面的很多容器不是线程安全的,但是 Java.util.Collections 可以帮你创建一些安全的版本。另外关注一下 Java.util.concurrent 里面有 ConcurrentMap 等容器可供使用。
  • 看看 Java memory model(内存一致性模型)和无锁同步(见 Java memory model 和 Java.util.concurrent.atomic)。
  • 了解一下 C++11 的 memory model。看看 Java 9 里为 Java.util.concurrent.atomic.AtomicInteger 等类增加的 Acquire 和 Release 语义的读写操作。
  • 了解一下除了“共享内存多线程编程”以外有没有别的模型(多进程 multi-processing、消息传递 message passing 等)。
  • 学学 MapReduce 的思想以及它的实现。

三、反射

学习 Java 的反射机制,以及 Annotation 的用法。

  • 试试 Java.lang.reflect.Proxy 的用法。
  • 玩一玩 CGLib(一个第三方的库)。
  • 看看 Java 9 里的 VarHandle。

四、网络编程

学习一下 IP, TCP 协议(计算机专业的应该学过,复习一下),学习 Socket编程(注意垃圾回收器不会帮你关掉 Socket)。

如果不是很关心 HTTP,看看 Java.nio,学习单线程轮询式 IO 复用(Selector)。

  1. 如果有点不明白 nio 的意图的话,了解一下 c10k 问题。http://www.kegel.com/c10k.html
  2. 了解一下操作系统(包括 C 语言)提供的 select, poll, epoll, kqueue 等接口。
  3. 试着用 Java.nio 写一个文件服务器。
  4. 上网扒一扒有没有其他的通信库,如 netty 等。
  5. 如果关心 Web 还有 HTTP,就学习一下 HTTP 协议,以及用 Java 进行 HTTP 的客户端编程。
    • 学学 HTML,写写 HTML 的静态网页(不需要 Java)
    • 用 Java 写一个基于 DOM、XPath 或者 CSS Selector 的网页解析器(爬网页)。
    • 学学 Java 的 Servlet 接口(先别学 jsp)进行 Web 服务器端编程。学学标准的 Servlet 容器怎么用,包括 web.xml 的用法以及 listener、filter 等概念。以及某个 Servlet 容器(如 Jetty 或者 Tomcat)的具体用法。
    • 试着学一种模板语言(如 haml, velocity, freemarker, String.format,如果真的想学 JSP 的话 JSP 倒是也行,但不推荐)。
    • 学学 Spring 框架中的 Web 框架,或者 Struts,看你的口味。
    • 看看 Spring Bean Container 以及里面各种乱七八糟的工具。
    • 了解一下什么是 RESTful Web Service,复习一下 HTTP,找找适合的 Java 工具。
    • 你可能会觉得 Jackson 是一个解析JSON好用的东西。

五、数据库

学习一下关系数据库(计算机专业的应该学过,复习一下),包括 SQL。

选一个数据库管理系统熟悉一下(比如 MariaDB,或者用被 Oracle 收购了的 MySQL。先脱离 Java 单独学学)。

然后看它们的官方文档教你怎么用 Java 连接这种数据库。这中间会涉及到 JDBC 接口。同时一定要知道 SQL 注入安全漏洞,以及掌握如何用 PreparedStatement 防止注入。

  • 可能中间会涉及“事务”问题,让你不知不觉地开始去了解 Java transaction api(JTA)。
  • 学一学对象关系转换(如 Hibernate)。
  • 也可以学学非关系数据库,以及如何用 Java 访问它们。

六、日志记录

Java的日志框架有很多,常用的有log4j1.x,log4j2.x,logback,jul,jcl等等,这些框架如何使用?他们如何与slf4j-api搭配使用?不搭配slf4j-api能否单独使用?使用过程中需要注意哪些事项?

  • slf4j 是怎么桥接这些框架的?为什么需要slf4j去链接这些框架。
  • springboot里用的是什么哪个日志框架?如何更改日志框架?
  • 淘一淘 Java.nio.files 里面有什么好用的,然后再淘一淘 Apache Commons Lang 和 Commons IO 里有什么好用的工具。Commons Logging 就不要再用了,用 slf4j 和 logback。

七、版本控制

学习一种分布式版本控制器(如 Git、Mercurial、Bzr、Darcs 等,推荐 Git)的基本用法,以及如何用它管理 Java 工程。希望你已经开始使用 Maven 了,并且知道为什么把 IDE 生成的工程文件(如 eclipse 的.project,.classpath 和.metadata)放入版本控制器不好(一般版本控制工具中需排除工程文件)。

  • 为你们实验室搭建一个 Linux+SSH+Git 服务器,装个 GitLab(一种 Web 界面)。
  • 了解“集中式版本控制器”和“分布式版本控制器”的区别,并说服同事们不要再用 SVN、CVS 或者 SourceSafe 等老旧的“集中式版本控制器”了。
  • 开设一个 GitHub 账户。如果你不喜欢 Git,就用 BitBucket 等。
  • 自己(或者为你们实验室)搭建一个持续集成(Continuous Integration)服务器,如 Jenkins,定期编译你的程序。建议同时使用 Git 等分布式版本控制器。
  • 如果你做开源软件,试试免费的 GitHub Actions。还有一些比如 Circle CI、Travis CI 都可以试试。

八、高效容器

学学 FastUtil 或者 Trove,如果你需要进行大量数值运算的话。

九、JVM(八股文重灾区)

  • 通读一遍Java Language Specification,以及 Java Virtual Machine Specification。
  • 深入研究下虚拟机层面的东西,比如字节码,类加载,JIT等等。有时候Java代码看不出来的问题,到字节码层面就很容易分析出来
  • 了解以下解释器(interpreter)、编译器(compiler)、即时编译器(just-in-time compiler)和优化器(optimiser)的概念。
  • 如果对编译器的话题不感到畏惧,了解一下 method JIT 和 tracing JIT 的概念和区别。
  • 学学JVM垃圾回收的几种基本算法,包括 mark-sweep、mark-compact、semi-space、generational、mark-region 等,各自的性能,以及为什么朴素的 reference counting 是不完整的。知道为什么 finalizer 性能很糟糕(在 Java 9 中已经被 deprecated,Java 18 中已经被 deprecated for removal)。
  • 了解一下什么是 GC 卡顿问题,以及 concurrent GC 如何实现(如 yieldpoint、read/write barrier 等实现技巧)。推荐 Richard Jones 等人著的《GC Handbook》。如果卡顿对你来说真的是个问题,试试 ZGC。
  • 了解一下如何设置 Java 虚拟机的堆大小限制(如 HotSpot 虚拟机的-Xmx 选项等)。
  • 了解一下 Java 里的 WeakReference 以及 SoftReference 和 PhantomReference,以及它们什么时候有用,以及为什么它们实现起来有些困难。
  • 如果有精力,了解一下 Hotspot 虚拟机的内存管理算法是什么样的。比如,了解一下 Java 9 开始默认的 GarbageFirst (G1)以及后来新加的 Shenandoah、ZGC 等 GC 算法的工作原理。

十、密码学(银行常考)

  • 学一学密码学,包括编码、密码分析、攻击、对称密钥、公钥系统、数字签名、哈希算法等,看看 Java 有没有实现。

十一、spring全家桶

  • 理清楚spring全家桶的发展历程,
  • 思考为什么要用spring,spirng相比传统Java框架有什么改变。
  • 了解spring框架中注解实现方式,自己能否定义一个注解?
  • 思考为什么IOC容器是spring的核心,AOP是Spring框架的重要组成部分,架构师创建这么专业的名词,他的本质是什么,是否可以自己写一个非常简单的demo。
  • 思考为什么要用springboot,相比spring有什么改变。
  • 了解最新的springboot3,将自己的代码升级springboot3,看一看会碰到哪些问题。
  • 思考微服务是个什么东西
  • 看一看spring cloud,没有spring cloud我们是怎么做如服务发现注册 、配置中心 、消息总线 、负载均衡 、断路器 、数据监控等操作,有了Spring Cloud 我们怎么实现微服务项目的构建。
  • 思考是否万物皆可微服务?游戏行业也是用微服务架构嘛?
  • 开始卷spring全家桶的源码,这里内容太多,建议在理解的基础上背八股文。比如面试中经常问的一个问题,如何解决spring框架中循环依赖问题?你需要从以下方面出发:1、为什么会发生循环依赖问题?通过查文章发现A->B,B->A,自己可以写一个简单的demo,复现循环依赖问题 2、循环依赖用三级缓存可以解决,是哪三级,那可以用两级缓存吗?

十二、思考

挖一挖历史上比较火的可能和 Java 相关的技术,或者后来被废弃了的技术。比如:

  • Applet,想想它比起 html5+css3+Javascript 的缺点在哪里。
  • AWT、Swing,想想为什么很少有人用 Java 写图形界面程序。你觉得 Swing 的程序看上去舒服吗?中国人和残疾人喜欢用 Swing 程序吗?
  • JNDI,想想它比起 Spring Bean Container 的缺点在哪里。
  • JSP,想想它比起 MVC 结构的缺点在哪里。
  • WSDL/SOAP,把它们和 XML-RPC、RESTful Web Service 比较一下。
  • XSLT,以及为什么它是图灵完备的。可是它真的比 Java 本身更好用吗?
  • Log4j、Java.util.logging、Apache Commons Logging,各自有什么问题,以及 Log4j 的作者本人为什么又开发了 SLF4j 和 Logback?
  • Java 最早是为什么设计的?
  • Type erasure 是怎么回事?为什么 ArrayList不行但 ArrayList就可以?挖一挖历史。
  • finalizer 在 Java 9 中被标记为 deprecated,为什么?
  • 微软的 Component Object Model(COM)当初是为什么设计的?它如何管理内存?那样管理内存有什么问题?后来为什么微软改推.NET 了?
  • 如果有兴趣的话,看看苹果的 Core Foundation 是什么样的?ObjectiveC 如何管理内存?Swift 呢?
  • HotSpot 里的 Concurrent Mark-Sweep(CMS)垃圾回收器为什么被弃用了?替代品 G1 怎么样。

最后,希望Java学习路线对你们有帮助。

推荐阅读:

有哪些值得计算机专业加入的国企?

第一次面阿里,难绷!

输了!广州某小厂一面,也凉了

浏览 663
3点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
3点赞
评论
收藏
分享

手机扫一扫分享

分享
举报