[译] 关于你的编程生涯的一些告诫

如何避免迷失在编程的黑色森林中

在个人编程生涯刚刚开始的时候,主要困扰个人一件事情就是编程语言/编程技术的选择。我应该学什么,从哪里入门?要获得个人第一份编程工做我须要学会什么?回望过去(距今大概已经 10 年),那时尚未像 CourseraUdemySoloLearn 这样的在线教育学习平台。那时的我也还没法全靠本身就能寻找到通往成功事业的正确方向和完整道路。对于程序员这个岗位,高回报、待遇好,简直堪称 21 世纪的宇航员。前端

一样的问题至今依然存在:初学者苦于选择。没有成为好程序员的直达途径,社区一般对于像“Python 是一门胶水语言吗???”这样的新手问题不太热情。通往成功的编程事业的道路彷佛比之前还更加迷茫。你(假设你是个初学者)必须面临如下选择:C++/C++11/C++14/C++17, Java, C#, Kotlin, PHP(神马?),Python, Node.js, JavaScript(慢着,还包括 Angular, React 或 Vue 吗?),等等。android

语言、技术、仍是技能?

为了回答这个关键的问题,我必须得先问你,你想要的是什么?你是对构建手机应用感兴趣、仍是对构建像 Facebook 和 Medium 这样的网站感兴趣、或者说你更想构建像 Photoshop 这样类型的桌面应用?仍是说你全身心喜好游戏开发?移动端游戏仍是桌面游戏?ios

为了获得一个科技公司的软件工程师职位,我应该学会什么?”,我以为回答这个问题最明智的方式就是先找出为了经过此次技术面试你必须掌握的关键技能。但咱们应该首先把事情整理稳当,如今让咱们深刻了解编程的世界、它的国家、城市,它的文化、战争,它的成功、失败。对于那些没有耐心看这么多的读者,你能够直接滚动到“为技术面试作准备”那一节。git

探索编程的世界首先让咱们面临着 3 大主要平台:程序员

  1. Web 端(像 Google 搜索引擎、Facebook、亚马逊、Twitter、诸如此类)
  2. 桌面端(像 Dropbox、Photoshop、Visual Studio、Skype 等等)
  3. 移动端SoloLearn、Instagram、Uber 以及其余)

其实以上所说的大部分服务几乎在三个平台上都有产品,好比 Skype 就有桌面应用、手机端应用以及 Web 应用(尽管作得很烂),Twitter 就有 Web 应用和手机端应用,诸如此类。github

Web

Web 在此语境下自己就是个巨大的概念,为了解释这个概念,咱们应该把它分为所谓的“前端”和“后端”,后者正是我我的所偏心的。前端就是你在网页上所能看见的东西,后端则为你所能看见的东西提供必不可少的支持。总的来讲就是,前端就是网站的外观和体验,后端了就是运行着用来处理用户请求的服务,包括像处理数据库查询诸如此类的事。面试

前端。若是你想精通如何处理网站的外观和体验,例如:构建精美绝伦的网站,让用户爱不释手,那你就应该学习 HTML(外观)、CSS(外观和体验)、JavaScrip(体验)。固然这还不够。从如今看来,使用纯 JavaScript 是不足够的,因此你得选择一个合适的框架,目前比较流行的有 Angular,React 和 Vue。选择哪一个主要取决于你最想去哪一个公司,Google 仍是 Facebook?若是是 Google 那就选 Angular,若是是 Facebook 那就选 React。若是两个都不喜欢(有点奇怪),那就选 Vue。简单明了!除了这些你还须要掌握一些基础概念,像 HTTP 协议的内部工做原理;你还须要熟悉一些 Web 服务器(至少不该该被像 Apache 和 Nginx 这样的名词吓坏)。成为一名前端工程师意味着你必需要渲染你从后台服务器获得的数据(为用户作美化),因此对像“什么是 API“、“什么是 JSON(以及为什么它比 XML 要好)”之类的问题有个最基本的了解是必须的。(若是以上所说的你有任何以为很陌生的,能够查看本文末尾“参考文献”那一节的内容)。算法

一张网络上描述前端和后端区别的趣图。数据库

后端。就是看不见的真理,道不清的故事了。在上古时代,了解 PHP 的话你就能够宣称本身是个后端工程师了,后来微软引入了 ASP.NET,二者相互角逐,直到 Node.js 驾着七彩祥云来到,整治混沌,让一切各得其所。在 Node.js 中,事件驱动开发的概念被应用得淋漓尽致,所以若是你选择了它,你就已经为你的项目帮了一个大忙。编程

后端领域中很使人困惑的一个部分就是它的语言多样性,就是说,你可使用任何你但愿使用的语言来实现后端,但关键是:“后端”自己是个简称,它包含了“查询数据库、处理数据、响应客户端,以及尽最大努力使得响应最高效”,这并不是你选择了“对的”语言/技术/数据库就搞定了的。有一些开发者选择相似 MySQL 或 PostgrSQL 这样的关系型数据库,也有一些新入圈的开发者选择了另外一种,就像 Cassandra 或 MongoDB。作出什么样的选择固然取决于你了,但我有个简单的法则。你的数据有严格的模式、而且在短期内不会发生改变?那就选择关系型数据库吧。你的服务每分钟有超过数百万的访问量了?那就得切换到 NoSQL 了(切换过程很蛋疼)。你的产品变化得很是迅速?那就选择 NoSQL。假如说你已经选择好了数据库类型了,那具体的数据库你应该怎么选呢?你喜欢微软而且有 Windows 服务器?那就选择 MsSQL。你喜欢 Oracle?那就选 Oracle 数据库。你对 Oracle 以为还行、可是同时又讨厌微软?那就选择 MySQL。或者说你谁也不肯得罪?那就选择 PostgreSQL 吧。

对 NoSQL 数据库的选择而言就略显纠结了。这真的取决于你的后端服务和数据架构。你只有一些文档而后它们之间的联系还很微弱?那就选 MongoDB 吧。你须要存储一大堆的键-值对?那就选 Redis。你正在处理像这种结构的数据(Facebook 的好友关系图,Google 的知识网络图,等等)?那就选 Neo4j。还不肯定你究竟须要什么,但你以为以上所说的你都须要?那就选 ArangoDB 吧。

数据库存储了全部必要的数据,同时你也应该定义一种 API,使得你的客户端能够经过它来请求对数据库进行读/写。这里更有用的选择就是 Node.js。Facebook 选择了 PHP 来做为它的后端实现,而后他们又用 C++ 重写了其中的很大一部分 PHP 代码。有人使用 Python 但也有人更喜欢 Ruby。确实是这样的,你能选择任何语言来实现后端服务。好比说:Google 使用 C++、Java 和 Python(跟 Go 结合使用)。对于底层的数据处理,C++ 最合适不过了;对于后台任务,像更新用户的朋友推荐,Java 是个好的选择;对于数据分析、天然语言处理或当今最流行的与人工智能相关的任务,你极可能会选择 Python。

重申一遍,后端除了各类各样的编程语言、框架、数据库,还有一些你必须掌握的核心概念。

  • 缓存。从底层的 CPU 缓存(有不一样层级的缓存)到顶层的浏览器缓存。处处都在使用缓存。对于高负载的服务,像 Google 搜索引擎或 Facebook,缓存都是相当重要的。
  • 服务器。你可能会以为这是关于硬件的(若是你知道怎么把多台计算机设置得像一台那样存储和处理数据的话,那最好不过了),对于后端工程师来讲,服务器仅意味着 Web 服务器。目前流行的 Web 服务器就是 Nginx,了解如何设置和配置 Nginx 对你之后的努力会有高回报的。
  • 套接字(Sockets)。网络编程的基石。你经过网络发送和接受的全部东西都是经过套接字完成的。了解套接字编程的底层细节在你的技能谱中是一种额外加成,要是了解 TCP 套接字和 UDP 套接字的区别以及什么是 WebSocket,那就更是极大的附加价值了。
  • 数据库设计。无论你本身选择或不得已使用哪一种数据库管理系统(DBMS),操做数据将是你的主要任务之一。看清整个数据库的大局、将数据可视化、了解数据单元之间的联系,在你的编程生涯中这些能力都是必须掌握的。
  • 安全性。与上述说起的概念不一样的是,这个概念相对很是普遍。你甚至不可能彻底掌握它,所以你至少要熟悉一些相关的最佳实践,好比不能明文存放密码,要使用密码的散列值/哈希值(hash);经过 API 令牌检查请求的有效性,以及对用户的每一个请求都要检验用户权限,诸如此类。

桌面端

咱们将会讨论桌面应用之因此为桌面应用最相关的那一部分。桌面端有成千上万须要特殊技能谱的桌面应用,例如 Photoshop 是处理图片的,那么若是你想开发相似于 Photoshop 这样的桌面应用,掌握处理图片的算法和技术对你来讲就是必须的;若是你想开发相似于 Dropbox 这样的应用,那么了解套接字编程就是必须的;若是你想开发编译器或像 Visual Studio 这样的 IDE,那么了解如何设计编译器就是必须的。咱们不会讨论这些特定的领域,咱们就探究一下你在桌面端开发中最可能使用到的语言吧。

当涉及到开发桌面端使用什么语言的时候,开发者一般会很艰难地在 C++,Java 和 C# 之间进行选择。我有一个简单地法则来作出正确地选择:若是你喜欢微软,那就选 C#;若是你喜欢 Oracle,那就选 Java;若是你以为一门编程语言不该该被某一个公司所拥有,那就选 C++。若是这个法则对你来讲不那么有效的话,咱们能够再探讨一下一些实际的子平台。若是你的应用目标群体只针对 Windows 用户,C# 是最佳选择,很明显,由于它们都是微软的产品,所以相互适配得很好。可能有些 C# 开发者坚持认为自从 .Net Core 发布以后,C# 也能够在 Linux 环境下开发,但我我的建议若是你想你的产品覆盖 Linux 平台的用户,最好仍是选择 C++。决策点就是,开发 C++ 的初衷就是让它做为一门跨平台的编程语言,也就是说它在任何操做系统下都可以运行良好(对的,包括 MacOS)。好吧,这里所说的跨平台假定了你必须在全部的操做系统上分别编译、而且迁移应用程序的“各类”可执行文件到各类具体的操做系统。坦白来讲,C++ 确实缺少图形化用户界面,最好的借口莫过于“C++ 原本就是为大神级开发者准备的,大神级的开发者一般都只用终端(命令行界面)”。不过,仍是有好心的开发者聚到一块儿开发了 Qt,这但是完美兼容 C++ 的跨平台图形化用户界面库。

最后一点,若是你很烦 C++ 的复杂性,很烦为了构建完整的图像化用户界面还不得不连接一个另外的像 Qt 这样的库,也很讨厌为了适配不一样的操做系统的用户而不得不在每一种操做系统上编译、移植你的应用,那就选择 Java 吧。Java 拥有本身的虚拟机,使得移植可执行文件很容易。你的应用将在全部安装了 JVM(Java 虚拟机)的操做系统上完美运行。

移动端

当谈到 Java 时,首先映入脑海的就是 Android 了。早在 Kotlin 问世以前,Java 就是开发 Android 应用的事实标准了。现现在,Kotlin 占据了开发者的心里,使得开发 Android 应用的体验更好。所以,若是你想开发 Android 应用的话,你应该在 Java 和 Kotlin 之间进行选择。为了作出正确的选择,咱们得看看幕后的真相。真相就是 Google 和 Oracle 不是很和谐,但 Oracle 拥有 Java,同时 Java 又主导了 Google 的 Android,所以为了灵活不受限于人,Google 不得不向邪恶势力(或者说正义,随你怎么说)低头,引入了 Kotlin,而且伪装说“哇,咱们支持这么好用的编程语言,大家就别再用 Java 啦”。若是你刚开始 Android 编程的话,我我的建议你从 Kotlin 入门,尽管为了在人才市场中提升竞争力你不得不为用 Java 实现的旧应用提供一些支持,因此这时候学会 Java 就会为你的简历增添一些亮点。

最后就是 iOS 了。所谓的 “iLand”(译注:因为苹果大部分产品都以 i 打头,原做者使用 iLand 表示苹果的产品线),就是全然不一样的故事了。很长一段时间内 Objective-C 都是 iOS 的主要开发语言,老实讲,不是随随便便就可以掌握 Objective-C 编程的,它须要坚决不移的毅力,这就是为数很少的 Objective-C 开发者的主要问题。苹果公司最终总算迈出正确的一步,引入了 Swift。Swift 相比 Objective-C 来说要容易得多,这使得 iOS 开发者数量有所上涨。因此说要成为 iOS 开发者,你得学习 Swift,但要成为合格的开发者,我还建议你要掌握 Objective-C,由于你须要给之前使用 Objective-C 编写的应用(有成千上万这样的应用)提供支持。

这里不得不提一下 React Native,由于它使得开发者可以仅仅使用 JavaScript 就同时为 Android 和 iOS 编写应用,可是 React Native 做为市场上一个新兴且善变的角色,咱们就让它刷一下存在感好了,若是你还会一些 JavaScript 的话,就权当你已经能编写一些简单的应用了。

为技术面试作准备

编程领域中有不少基础的概念。大部分技术面试目的都是发现你解决问题的能力以及是否了解这些概念,因此除了掌握一门编程语言以外,你还要熟悉这些概念,某种程度上讲,这些概念在程序员的技能谱中是必须的。如下是我最近在 SoloLearn 上发布的课程的概要,下面是 SoloLearn 的 Android 和 iOS 应用下载地址。

为了成功为技术面试作准备,你必须对如下的领域感到很是自信:

  1. 算法与数据结构
  2. 计算机组成结构与操做系统
  3. 编程
  4. 系统设计

算法与数据结构 这是程序员最须要的技能谱。如下是每个程序员都必须熟知的:

算法复杂度:大 O 记法和如何计算算法复杂度;掌握如何根据算法的复杂度来比较算法的优劣,如 O(N) 和 O(logN) 孰优孰劣。

基本数据结构和适配器:数组、链表、栈、队列。

排序与查找:掌握各类排序算法可以帮你定下项目的最佳可能实现。做为练习,尝试一下本身实现插入排序、选择排序和归并排序,而后找出线性查找和二分查找的不一样点。

树、图:处处都有树和图的踪迹,从 Facebook 的“朋友关系图”,到 Google 的“知识联系图”。

散列表/哈希表:史上最高效的数据结构,散列表老是一个好的选择。你应该要可以本身实现一个散列表,并熟知解决哈希冲突的技术。

计算机组成结构与操做系统 强烈建议你要熟悉如下主题:

  • 位运算
  • CPU 如何执行机器代码
  • 静态随机访问存储(RAM) 和动态随机访问存储(RAM)的区别
  • 有哪些类型的操做系统内核
  • “互斥锁”和“信号量”的区别
  • 什么是死锁、什么是活锁

编程 你应该精通至少一门编程语言。知道你最喜好的那门编程语言的优点、劣势以及最佳实践总会帮你写出更高效、更优雅和可读性更强的代码。 强烈建议你经过解决有挑战的难题来练习编程,比方说(如下问题均可以在 SoloLearn 找到):

  • 约瑟夫问题
  • 汉诺塔
  • 字符串压缩
  • 匹配的括号
  • 孪生素数

系统设计 了解面向对象编程是现代程序员的必备技能。 系统设计意味着要考虑整个系统、可以设计其架构、将其分解成一个个的类、定义对象之间的交互。 尝试回答如下问题来对此作准备:

  • 若是是你,你会怎么设计 Google 搜索引擎?若是每秒有上百万请求同时来到怎么办?
  • 若是是你,你会怎么实现 Facebook 的好友搜索?
  • 什么状况下你会使用关系型数据库管理系统?
  • 什么状况下你会使用 NoSQL 数据库?

强烈建议你学习和使用正确的设计模式。好比你应该了解组合模式和装饰器模式的区别。

尽管一般都只要求初级开发者拥有良好的解决问题的能力,你的第一份工做可能也不会要求你了解以上所列的全部点,但这个列表仍是能帮助你规划之后的职业生涯。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索