大学学Java和C++哪个好找工作,哪些才是重点?

作者 | 编程指南

出品 | 编程指南(ID:cs_dev)

头图 | CSDN从视觉中国下载

前言

为什么突然想写这个话题?

最近有很多新关注的读者在后台问:大学找工作学Java还是C++哪个好,学前端还是后端,学Vue还是React。. .

好像看到了自己当年的样子,所以觉得有必要单独写一篇文章,作为计算机应届毕业生来聊一聊。我认为在大学的四年里,计算机学生应该学习什么和哪些是关键点。

同样的大学四年,为什么有的同学毕业后能成为大厂Offer收割机,各种SP和SSP都软了,有的同学在学校写了很多网站,项目经验也很全。工作很难。

不能说后者没有好好学习,或许努力的方向错了。

废话不多说,让我们直奔主题。

文本

人类知识的边界在不断扩大。俗话说,学无止境。这也适用于计算机领域。计算机本身是一门人造科学,而不是一门自然科学。

每年,甚至每个月,都会不断推出新的编程框架。光头是学不完的,没必要一一学。

而且你会发现很多一二线工厂都使用自己的内部工具,比如服务发现、RPC、KV、DB、消息队列、日志、监控等等。

所以一般来说,这些大公司在招人的时候,基本不会因为没有学过某个框架就挂你。反正很多东西都要进来再学习。

他们将更多地关注你的基础知识、解决问题的经验,以及更普遍的聪明才智。

相反,一些小公司可能会要求你了解 Spring、Vue、Redis……这些框架或组件。

腾讯京东

阿里京东

外包的京东

以上是腾讯、阿里巴巴、外包公司的招聘JD(job deion)。显然,腾讯和阿里巴巴对扎实的基本编程能力和快速学习能力感兴趣,这意味着有培训的潜力。

外包公司要求你了解xx数据库,Spring之类的。我不想评价哪个更好,但如果你想去BAT,至少对他们的JD来说,提高你的能力是一条捷径。

在这里,我将计算机编程领域的知识大致分为三个部分:

基础知识是指任何方向的软件工程师都应该掌握的知识,比如数据结构、算法、操作系统。

领域专业知识是你在从事某个细分方向时需要掌握的知识。比如你是游戏引擎,你需要掌握图形;如果你是前端,你需要掌握浏览器渲染的原理和三个前端;算法工程师需要更多的数学知识。

毕竟电脑门类挺多的,需要选择一个细分领域去学习,而且只有什么都学,才会什么都擅长(大佬除外。

基础知识

现在大环境比较浮躁,很少有人愿意把时间花在基础上,喜欢直接学Python搞机器学习,写秒杀,做商场。

在找工作的时候,我只想读经,总结一下速成结果。

但是作为一名优秀的计算机专业的学生,​​怎么会在各种编程框架中(除了构建框架),纠缠于学习SpringBoot或SSH?

把时间花在算法和基础科目上不是很好吗?在功利主义方面,回报会更大。

而且,在计算机领域,很多基础理论都不是很先进,我们可以通过努力掌握核心知识。

1、数学

首先,这里列出数学不是为了显得高端,而是要遭受数学损失。

如果你是自学成才转行做程序员,当然不推荐数学,因为转行大概率是学Java、前端等,对数学基本没有要求。

不过,这篇文章主要针对还在读大学的学生。这些学生可能会做算法(CV、NLP等)、游戏引擎、信息安全编码等。

这些方向会有很高的数学要求。在计算机领域,线生成、概率论、统计学等数学分支比较重要,计算机在本质上还是离散的。

例如,在机器学习或数据挖掘中,经常使用线性代数来降低数据维度,许多问题最终都可以简化为求解线性方程组。

所以为了避免以后想学这些方向的时候被数学卡住,我应该在一、大二上数学课的时候好好学习一下。

当这本书在使用时,你会少讨厌它。不要觉得没用,也不要努力学习。当你需要它的时候可编程计算器怎么用,你会知道你会后悔的。(默默流下无知的眼泪┭┮﹏┭┮

什么?你说以后一定会做发展方向?

确实可以把数学放在后面一点,确实用的不多,但是在数学课上一定要认真听,拿到高分也无妨。也许有一天你想再次加入算法卷积的大军?

2、C 语言

你可能会很困惑,基础知识就到这里了,为什么要单独列出一种编程语言呢?

因为在我看来,没有比 C 语言更好的理解计算机系统的语言了。

我们后面会提到的操作系统和架构非常适合用C语言来理解或练习。

而且C语言本身的语言特性很少,但是要学好也不容易。很多人认为C语言很难。困难在哪里?回想一下我大一时的感受:

不幸的是,这些东西都是计算机系统知识的一部分,所以使用C语言作为学习计算机系统知识的最有效方式。

真的很难想象用 Java 或 Python 向别人解释记忆,因为这些语言比 C 语言的抽象层次更高,这意味着离计算机系统更远。

在 TIOBE 编程语言排行榜上,C 语言几乎总是占据前三名,其地位自然是毋庸置疑的。

TIOBE-2020 排行榜

而且你在开发中使用的几乎很多东西都是用C语言编写的,Linux、Nginx、Redis、MySQL、Git……也许你想探索一下原理,阅读这些开源软件的源代码,那么C语言也是你必备的瑞士军刀。

深度学习C语言,能够理解计算机底层执行原理,是理解程序运行机制的优秀语言,无以伦比。

在这里,我不得不引用C语言最经典的总结:

任何低于 C 语言的语言都不足以完全抽象出一个计算机系统;任何高于 C 的语言都可以用 C 实现。

这是一个很高很中肯的评价!

所以对于计算机科学课,不管你是做前端还是后端,算法还是开发,都推荐C语言让你好好学习。这是一种没有方向的语言,它是基础!

3、操作系统

我们编写的 IDE 和我们编写的程序都需要在操作系统上运行。毫不夸张地说,操作系统是计算机软件的基石。

程序运行时,需要创建一个进程,这涉及到操作系统的进程管理;写程序需要定义变量和存储数据,这也涉及到内存,对应内存管理;有时我们还需要读写文件,这与文件系统的处理是分不开的;您需要学习使用锁、条件变量和临界区来保持程序同时运行而不会混淆。

读写文件和分配内存都离不开系统调用。

而当你真正开始一个项目的时候,你会发现很多问题都和操作系统息息相关。如果你不了解操作系统,你甚至无法分析问题的原因。

比如前段时间,在基于协程(libco)的框架下,我们使用多线程锁做同步互斥和偶发死锁。后来分析发现原因:

由于协程是在应用层实现的,一个线程中的多个协程对操作系统来说是不可见的:

协程模型

那么当一个协程A被锁,发起网络IO请求时,此时会切换到另一个协程B,协程B会再次请求锁。

这时候操作系统会认为锁已经被锁了,所以会将协程B对应的线程挂起到等待队列中,这样会导致协程A永远运行不起来,锁也不会被释放,导致死锁。

解决方法也很简单,就是把锁设置为可重入锁。重入意味着同一个线程多次请求同一个锁不会导致挂起。这样,当协程 B 再次请求锁时,操作系统会认为协程 B 所在的线程已经持有锁,直接返回继续执行。

简而言之,我们一直在编写与操作系统交互的程序,没有理由不学好它。

4、编译原理

编译原理可能是我们平时接触最少的。你可能觉得不需要创建新的编程语言,那么为什么要学习编译原理呢?

学习编译原理有什么用?

你会从更高的角度看待这些编程语言,你不会再看到表面的语法,而是会思考语法背后的实现。

这种感觉很透彻,就像了解了操作系统和架构,你就会明白一个程序是如何从双击鼠标开始的,以及它是如何运行的。这种把所有细节都掌握得淋漓尽致的感觉,着实令人惊叹。你去试试。

说英语!

那么在学习了编译原理之后可以做什么呢?

当你学完有限状态机后,你会发现你曾经认为正则表达式很牛逼,现在看来你可以自己使用 DFA 和 NFA 来实现它们。状态机的思想在编程中很多地方都用到了。

比如解析HTTP协议的时候,如果你还没有学过状态机的思想,你可能会逐行解析if/else。这里最麻烦的是if/else需要提前接收所有的HTTP头字段然后判断,而且我们知道HTTP是基于TCP的,而TCP是流式的,所以你最有可能成组接收几个字符。这时候用if/else写出来就很丑了。

用状态机编写的代码非常优雅。状态的转换是由规则驱动的,接收到一个字符后判断是非常方便的。

继续学习语法分析,你就会掌握递归下降分析这个非常重要的思想,可以使用递归下降快速实现四个算术计算器。

如果不使用递归下降,可能需要先将中缀表达式转换为后缀,然后再求值。这是我们大一的数据结构类里写的,当时是用栈写的,有点麻烦。后来学了编译原理后,又用递归下降重写了一遍,几十行代码就搞定了。

还有另一种场景在实际开发中被大量使用。比如淘宝、京东等电商有很多营销规则,比如全减、直减、跨店等等,这样的规则是写不完的。在代码中。

这是怎么做的?

一般是实现一个配置系统,设计一种DSL(domain-specific language)来表达这些规则,将规则直接配置到系统中,可以很方便地进行修改。那么如何解析代码中DSL定义的规则呢?这就需要为DSL写一个解析器,这里会用到解析的方法。

DSL(Domain Specific Language)是一种针对特定领域的编程语言。这个特定领域是相对于通用语言如C、C++和Python而言的。通用语言可以用于各个领域。我们熟悉的大多数编程语言都是通用语言,并且是图灵完备的。的。

就像我们通常使用的 JSON、SQL 和 HTML 一样,这些都被认为是一种 DSL。你甚至可以尝试写一个递归下降的 JSON 和 XML 解析器,这比写一个电子商务网站更有价值。

继续学习如何生成抽象语法树AST,如何将其转换为中间代码,如何优化中间代码,最后如何生成机器指令。

您将看到贪婪算法在寄存器分配中的应用,您还将看到图论中的可达性分析如何实现死代码消除。

IDE 上的绿色编译按钮对您来说不再是黑魔法。

为什么单击可以生成可执行程序?

你写的英文字母是怎么变成二进制指令的?

学会了编译原理,这些都不是问题,妈妈再也不用担心你的学习了~

当然,像 GCC 和 Clang 这样的编译器完成起来太难了。学习编译原理的目的不是为了造一个这样的轮子,而是为了更好地理解和使用编程语言。

5、架构与构图

以上都是关于软件层面的,架构是关于计算机如何工作的,你会看到典型的存储程序计算机是如何工作的。

我记得南大的一位老师说:“我们不学习使用计算机,而是学习如何构建计算机。” 虽然造计算机有点夸张,但至少我们要了解计算机的实现原理,以及代码是如何被 CPU 执行的。? 否则,你实际上会很困惑。很明显,一堆英文字母可以在CPU这样的电路上运行。大一时被C语言迷惑,直到学会了作文原理和数字逻辑。

我们说计算机中的一切都是0、1,而0、1用高低电平表示,二进制数值运算用AND、OR、NOT等逻辑门电路表示,然后将这些Simple电路集成在一起,形成ALU等具有计算能力的处理器。

您将看到 CPU 如何执行指令。CPU 从内存或高速缓存中取出指令,将其放入指令寄存器,然后对指令进行解码。解码就是根据指令的编码规则将指令拆分成一系列微操作和操作数。然后发出各种设备控制指令来执行微操作。这样就完成了一条指令的执行。

我们说过,学习了编译原理,你就可以理解写出来的英文代码是如何变成二进制指令的,而学习操作系统之后,你就可以理解二进制程序是如何链接在一起的,以及它们是如何被加载执行的。操作系统。组成原理会告诉你二进制指令是如何控制CPU运行的。我们的操作系统本质上是一个二进制程序。

当您了解计算机存储层次结构并了解多级缓存时,您将能够通过优化数据访问方式来编写更快的程序。

您将了解底层架构对堆栈帧和 C 等语言中的参数传递的支持。参数如何传递给另一个函数?如何获取函数的返回值。

这就是学习组合原理对编写代码的意义。

学习这些有什么意义?

你会完全看到写出来的代码是如何变成二进制指令的,如何控制各种门电路,最后变成屏幕上的彩色程序(当然,这里你可能还需要学习显示原理),这就是我们常说的说“基本”和“原则”。

而计算机体系结构中的很多思想都可以广泛应用于现代软件开发中,比如CPU的多级Cache思想,它是服务器开发中常用的提高并发性的缓存技术,包括缓存替换策略等等。

当计算机不再是你的黑匣子时,你了解你编写的代码到执行的每一步,这也将成为你未来的核心竞争力。作为一名毕业生,你不应该只使用 Java、Redis、Mysql、Spring 来编写各种网站。

如果有读者中途转行或者从培训课程中走出来,希望大家可以抽空补上这些基础课程,让自己在编程的道路上走的更远更稳。

6、数据结构和算法

为什么将算法放在最后并不重要?相反,它是如此重要,以至于它是结局。

如果你想问我大学最后悔的事情是什么?那一定是因为我从大一开始就没有开始学习算法和玩ACM。

一、 还在大二的同学不要抓住机会,不要等到以后后悔。当然,不玩ACM,我们也可以学好数据结构和算法。

您可以在任何计算机领域看到数据结构和算法。比如在编译原理中,寄存器分配会使用贪婪,死码检测和消除会使用图论中不可达的知识;操作系统进程和线程调度将采用多级队列和调度算法;组合原理中Cache的替换会使用LRU、FIFO等算法;必要数据库的开发也离不开B+树、LSM等数据结构和搜索算法。

很多时候我们需要的算法都被封装到了编程语言的基础库中,以至于很多同学会觉得算法离我们太远了,其实不然。

如果你不学习算法,你甚至无法分辨何时使用 Map(由红黑树实现)以及何时使用 HashMap。

所以学习算法帮助我们根据应用场景选择最合适的数据结构。

算法一定离不开日常开发。比如小北最近工作中涉及到的某个嵌套TLV(Tag-Length-Value)结构代码的分析,需要用到递归、多叉树等知识。如果不学习算法,只能在程序中看到很多if/else、while/for。. .

可以说,不懂算法的工程师一定不是好工程师。

7、我为什么不说网络、数据库等。

许多人喜欢将计算机网络和数据库原理归类为计算机基础。当然,我也同意,因为拥有完整知识结构的计算机科学专业的学生应该了解这些知识。

但我个人认为,计算机网络和数据库无非是基于操作系统、编译原理、组合原理的应用层软件。

什么是数据库?在没有数据库之前,你会使用文件来存储数据,但不方便搜索、修改等。数据库只是提高了这个过程的效率。

网络是做什么的?网络就是让不在同一台计算机上的程序相互通信,它本质上是一种进程间通信的手段。

如果只开发单机工业软件,确实是学不会网络的,但是因为大部分程序员都在互联网公司工作,无论前端后端,都离不开网络协议如HTTP。

重申一下:不是网络和数据库不重要,而是我认为它们属于建立在操作系统上的软件,不包括在基础中。

领域知识

这个我不敢多说,因为我对各个领域都不是很了解。稍微提一下,就是抛砖引玉。

如果你想去腾讯和网易做游戏引擎开发,那么图形一定是你绕不过去的知识。此外,你还要学习渲染管线、着色器、物理、光照等。

如果你想去PingCap这样的公司做分布式存储,那么分布式理论的知识对你来说一定是一个绕不开的关口,包括CAP定理、Paxos算法、Raft算法、ZAB协议等等。

如果你想写一个数据库,那么你需要了解磁盘、索引实现、SQL解析(编译原理)、事务、如何使用MVCC解决读写冲突等等,以及很多的编程语言层次。诸如锁、信号量、并发编程技巧之类的东西,不得不说,建数据库是一件脏活累活的活。

更进一步,如果你想做一个分布式数据库,你可能要学习数据分片的知识,如何做查询任务,是集中做,还是把逻辑下推到每个节点,如何实现分布式事务,以及很快。

你说你只想去大厂CRUD?没问题,老铁!

那你要熟悉一门编译语言(C/C++、Java、Go),了解该语言的一些底层原理,比如C++,你要看看STL,看看对象模型,你不用不知道虚函数表、智能指针等想去腾讯写C++?Java,你要记住JVM,什么垃圾回收算法,你不看ConcurrentHashMap,你都不好意思说你在做Java?

我们 CRUD 的对象是数据库,对吧?它一定不能学会如何善用数据库。用户通过HTTP访问我们的服务,你一定了解HTTP吧?对了,别看TCP三向握手和四向挥手,你还好意思说你是学计算机的?

当用户把钱和信息放在我们身上时,我们必须确保用户数据的安全,对吗?XSS、SQL注入、CSRF等常见的web攻击手段你一定要了解吗?您必须了解HTTPS、RSA、签名和数字证书的安全方法。

双十一流量太大,老板让你顶一下。那你得了解一下缓存、异步、消息队列、NoSQL,这些是千万QPS必备的杀手锏吧?

看一看!做好 CRUD 并不是那么容易。

(上一段只是另一种写出后端同学需要学习的知识的方式。不是吐槽,也不是玩笑,纯属娱乐。

技能

这很多,包括VSCode、Jetbrains等IDE,以及文档编写Markdown、Git等版本管理工具。SSH远程登录、端口转发、Ngrok内网穿透等提高你开发效率的工具都是技巧。这没什么好说的。通常,多学习和积累是好的。

我只提一点,尽快使用Linux,类Unix(Mac)作为主要开发计算机。大二的时候,刚看了王颖的文章《Working Completely with Linux》,买了一块SSD放在U盘壳上,做了个启动盘。后来,我用了将近一年的 Ubuntu。、提交作业等需要IE浏览器打开Windows(这里不得不吐槽老派网站!)

当然,我不是 Linux 的狂热爱好者,但我只是觉得,如果你在做开发,就离不开各种环境的安装和命令行的使用。类Unix系统在这方面有着天然的优势,用过的人都知道!

总结

写完才发现这篇文章的长度是《基础:领域知识:技能》,接近7:2:1。

这也是我建议你在大学期间分配学习时间的比例。至少50%的时间学习基础知识不少于50%。当然,学完这些东西后,你就可以往自己感兴趣的方向去学习了。

不要在大二的时候就开始研究 Java Web 和 Python 爬虫之类的东西。这些可以学习,但不是重点。

由于本文篇幅所限,我没有写关于如何学习它以及那里有什么好的材料。我要为这篇文章单独写一个“How Chapter”,继续关注我吧~

那么如何检查你的学习情况呢?

你一定听说过这个面试问题:“从 URL 输入到页面显示会发生什么?”

换句话说,这个问题是“如何将数据包发送到另一台计算机”。

如果你能完整地描述整个过程,那么你一定了解过网络!这就是为什么面试官喜欢问这个问题的原因。

所以我们根据葫芦画问一个问题

“从编写代码到程序运行之间会发生什么?”

这个问题的答案越详细越好。基本上,如果能解释清楚,编译原理、操作系统、组成原理这三个专业就懂了。

这个问题也放在这里,后续文章总结,请继续关注编程指南。

唉,要是这么有爱心的前辈告诉我,我也不会玩半年Andorid开发、Java Web、Python爬虫了。. .

不过好在后来才意识到基础的重要性,开始学汇编可编程计算器怎么用,重新学C,搞mini os,读Linux内核实现原理,终于成功脱发了一把。. .

最后,我想给你一些我非常喜欢的东西:

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论