编程工作的类别

Tags: Notes
Published:2025-03-23 21:57
Last Updated:2025-03-23 21:58

「程序员」这个称呼让人联想到「技术员」,似乎带有某种地位的隐喻。在按照掌握权力的多寡来进行社会分层的这里,「某某员」暗示了低下的社会地位,令人生厌。在网上,按照经济能力进行网络社会分层的各个社区,「程序员」又成为了某种值得羡慕的角色。但为了避免那个令人不快的暗示,大家用「转码」来指代学习编码、从事「程序员」工作这件事。

正式工作一些年了,我想我的工作也属于这个编程的范畴,但是对这个行业的分工和整体的了解却总觉得不够。我花了点时间把我知道的信息重新整理,制作了MindMap来帮助我自己理解,现在再花点时间写成文字,作为思考的最后一个阶段。

挂一漏万,这个行业的岗位特化非常显著(比如游戏行业),我只列出一些常见的、普遍的,以及我自己比较了解的领域。

在这篇文章中,我一律用「某某工程师」这个词,而不是「某某开发」,但其含义是一致的。同样的,用Cpp来指代C++,来避免大量输入「\」符号。

以下内容包含大量我的个人偏见,请保持理性,不必全信。

不写代码的岗位

项目经理 Project Manager

这一般是个领导岗位,管人、管钱、管项目,也要负责和不同的团队进行协调沟通(拉通对齐、吵架争功甩锅),说实话,要求挺高的。废物项目经理就是一个只能按公司流程填填报表、发发邮件提醒团队的各个职能角色要按公司的最新流程去做这做那的传声筒和橡皮图章。

产品经理 Product Manager

在互联网公司中常见,我没有接触过。

从网上的讨论中可以感觉到这是一个不写代码的、提需求的角色,常常引起写代码的同事反感。同时,我对其提出的需求能不能代表「用户需求」存疑。但是好的产品经理似乎也挺厉害,这个岗位看起来挺吸引人的。还有那句「人人都是产品经理」的口号,更是让人向往。

架构师 Architect

无论公司大小,似乎都会设置的一个角色。属于资深技术型岗位,但我从工作经历来看,这个角色一般脱离实际业务很久了,也不写业务代码,说是「架构」但是也说不清楚到底「架构」了什么,各个具体的项目一般不会受这个角色的节制。

这个角色最大的作用,我感觉是在不懂技术的领导面前为技术产品背锅的。当然,如果此人比较刻薄,必定会把这个气撒到名义上归其节制的各个项目领导那里去。

但顾名思义,一个合格的架构师似乎是应该跨项目,甚至跨部门设计统一的技术架构的。具体架构什么,应该跟该公司(部门)的具体业务相关。比如云架构师,可能要架构一下网络,统一规划一下各个项目使用的专用网络的层级和网关等等。除了容易想到的网络,还有别的方面,我并不是很清楚。

业务分析师 Business Analyst

从我对这个岗位有限的认识来看,基本等同于产品经理。都是和程序员配合,主要是提需求,但是又不写代码的。并且提出的需求并不一定是最终的用户的需求。似乎他们是一个翻译机器。

不写工程代码的岗位

(数据)分析师 Analyst

即便是传统的行业里也会有这个角色,主要任务是分析公司运营中产生的各类数据。这个岗位需要写代码,但主要是为了得到领导想看到的结论,画出漂亮的图表,讲一个好故事。至于代码本身,只是一个工具。如果有不需要写代码的工具,他们是乐于使用的,比如 Excel。

这个岗位对业务背景知识的要求比较高,对代码能力的要求较低。

算法研究员 Researcher

就是被广大学子津津乐道的「算法岗」。主要研究具体业务背景下的(机器学习/人工智能)算法,主要目标是发论文、提出可能的技术方案(即从特征提取到模型搭建到模型性能的一整套理论)。写代码,但写的是大学里面分析、研究性质的代码,只要能辅助他们得到结果,对代码的风格、潜在的风险、工程部署上的接口等等问题不予考虑。

Jupyter Notebooks 是最常见的工具。也许也可以包括Matlab?

常见的有广告推荐算法、内容推荐算法、自动驾驶寻路算法、自然语言处理算法(已经被大语言模型带到了普通公司承担不起成本的程度了)等等。

这个方向有工程化的岗位,需要写工程(业务)代码,下面详述。

写工程代码的岗位

传统软件开发,普遍需要涉及下面这些领域。但如今随着领域细分和新的市场需求的出现,有了一些行业(业务)特化的岗位,难以完全归类其中。

前端工程师 Frontend Engineer

前端就是接触用户的那一端,搞前端的基本就是写用户界面的(写UI User Interface 的)。随着现代技术的发展,网页也好,手机的应用程序也罢,都和用户有了更丰富的交互方式,因此搞前端的也拓展了职责范围到了用户体验上(搞UX User Experience)的。

根据用户使用的浏览工具的不同,又可以细分到下面这些领域:

网页端 Web

我觉得这个是鼻祖,也是最广泛的。说前端不加任何前缀或者解释的时候,一般默认是Web前端。

一般需要掌握这些概念和技能:HTML (网页背后的源代码就是用这个标记型语言写的,Markdown是它的超级简化版),CSS (用这个来定义网页上各个元素的样式,比如位置、大小、颜色、透明度等等),JavaScript 和 DOM (Document Object Model),就了解行业而言,不必过分纠结它们是什么。

常用的框架有React,Angular,Vue.js等等。

这是一个门槛相对较低的领域,这些框架和概念、技能,不需要太多前置的知识和经验就可以直接上手。有设计师从前端着手转行到写代码的这一行的例子。

移动端 Mobile

就是苹果iOS和安卓Android两大阵营。从使用的角度来看我很熟悉,但是从开发的角度来看,我完全不了解,因此不过多陈述。

但据我所知,这个领域也是从 Web 的体系沿袭而来的,可能一些基础的概念有共通之处。

桌面端 Desktop

(不必纠结Laptop还是Desktop,电脑拿不拿得动、放桌面上还是大腿上都不影响这个分类)

主流是 Windows,这些年随着苹果公司的大众化,MacOS 也成了一个流派。Linux 发行版太小众,主要用户是企业用户,也不太在意 UI,因此略过不谈。

常见的工具有用 Cpp 画 UI 的Qt,给 Python 用的 Tkinter 和「臭名昭著」的Electron。但我不知道为什么说它「臭名昭著」。

后端工程师 Backend Engineer

只有用户界面是没用的,想要有功能,必须有提供服务的后端。后端一般是用户接触不到的,只能通过前端来进行有限的操作。极端情况下,后端可以是和前端一起打包到软件里的一个表格文件和一些图片。你在界面上点了一个按钮,软件就把表格中的一部分呈现给你,你点了另一个按钮,就把图片随机展示给你。这种情况下,后端甚至不需要一台服务器。

当然,更常见的情况下,软件给用户提供的服务要更复杂得多,是通过服务器(可以理解成不给普通人使用的,甚至可以没有屏幕、键盘、鼠标等等东西的电脑)提供的。

写后端的,就是在服务器上写代码提供这些服务的,从而可以让用户在界面上点一点按钮就得到他们想得到的东西。庸俗化的后端(在最常见的业务领域,比如某小型企业的库存系统)就是处理前端传过来的查询数据的请求。该公司业务数据存储在后端的数据库中,前端发来用户的指令,后端根据这些指令写代码操作数据库,再返回相应的数据。所谓「增删改查」选手,也就是「CRUD Boy」 (Create,Read,Update,Delete,即增删改查,数据库的基本操作)。程序员学的一身屠龙技,在此全部用不上。

前端(点按钮)和后端(返回用户想要的东西)之间靠的是叫做 API 的东西沟通的。API 就是 Application Programming Interface 的缩写,此处请注意一下,这个 API 在两个不同的语境下有不同的含义。在前后端开发的语境下,API 指的是一种看起来像个网址一样的东西,前后端程序之间用它来进行交流。

后端开发需要掌握的技能比前端多一些,也难一些,门槛也相应的要高一些,甚至需要一些同样比较难的前置知识。常见的编程语言有Java,Cpp,Python,Ruby等等,如果硬要归类到编程语言的话,那么也算上 SQL 和 .NET (Windows专属)。

后端这边也有「框架」的概念,你可能会看到一些熟悉的词:Python 用的 Flask 和 Django,Java 的 Spring Boot,Node.js 的 Express.js 等等。框架之争和「最好的编程语言」之争一样,都是一个经久不衰的引战话题。

需要注意的是后端这里开始出现一些你可能会觉得眼熟的概念了。

比如「面向对象编程 (Object-Oriented Programming)」,常常和下面这些概念形成对立,并且成为引战话题:脚本(Script)、面向过程编程、函数化编程等等。其中,函数化编程始终站在鄙视链顶端,而「脚本小子」则永远在最下面。

有意思的,OOP 语境中也有一个 API,不过这回它是一个概念,而不是一个看起来像网址一样的东西。这个API指的是一个「类 (Class)」给外面提供的「方法 (Method)」或者「接口 (Interface)」。比如说一个叫做「汽车」的类,可能会提供这样的API:「启动引擎」或者「关闭引擎」。请不要和Web开发中用到的那个术语混淆。

当然,也会接触「安全」这个概念。比如 SQL注入,XSS (Cross Site Scripting)等等。主要是前端被不当使用,从而给后端传来了攻击性的指令,而后端提供的API没有识别和阻止这样的指令,从而把本不该发给前端的信息发送过去,或者把本不该执行的命令执行了(比如自毁指令)。

还有登录(身份验证) Authentication、授权 Authorization,以及中间件(Middleware)、微服务(MicroService)这样的概念。

还有对象-关系映射(O.R.M. Object Relation Mapping),主要用于在面向对象编程语言(如 Python、Java)和关系型数据库(如 MySQL、PostgreSQL)之间建立映射关系,使开发者可以使用面向对象的方式操作数据库,而无需直接编写 SQL 语句。

最后,从一个比较宽泛的角度来讲,前-后是对立的,如果你没有开发涉及用户的代码,那么笼统地讲,你就是「后端」。但是这个划分太粗了,毕竟除了 CRUD 之外,还有更专业的领域呢。比如建立、维护和管理数据库,或者开发一个基于机器学习的特定服务。

当然,调用其他人提供的服务,集成在自己的服务中,也是后端的工作之一。比如说调用微信支付的接口,或者查询12306的剩余车票数量。

运维 DevOps/Operations

上面说的不管是前端还是后端,都写的是和业务直接相关的代码(我称之为业务代码)。但是为了做出这个软件产品,除了业务代码还有一些非业务代码也需要人来写、来维护,俗称「搭环境的」。

这个角色有点像「服务器管理员 Server Administrator」,负责提供运行程序的必要环境(试想一下,你想学Cpp,但是发现你的电脑上怎么没办法像别人的电脑一样,按一下F5就把你写的printf()输出出来)。现代运维的职责也大大扩展,比如云平台上的基础服务搭建(Cloud Infrastructure)等等。

比较重要的概念和技术有容器化 (Docker, Image,Container 等等)、Kubernetes(K8s),自动化部署(持续部署)(CD,Continuous Deployment),持续集成(Continuous Integration)等等。

运维关注的是某种「自动化」,比如提交代码自动触发后续的单元测试、集成测试,进而生成一份报告,甚至直接部署到生产环境。和为了更方便实现和管理这种自动化的各种工具以及概念,比如 Infrastructure As Code 等等。

这个岗位也负责监控生产环境的各个指标,让程序生成关键日志、即使发出警报等等。

DevOps 是指一个既负责开发,又负责运维的角色。通常被我一并放在运维这边。

测试 Testing/Q.A. (Quality Assurance)

这里要事先声明一下,不涉及软件开发的公司也有「质量管理」这个岗位,讲究6 Sigma,标准化什么的。我这里说的是软件开发相关的招聘描述中出现的QA。这种QA仔细看岗位职责的话,通常可以和测试等同。

测试又分单元测试(Unit Tests)通常是开发人员自己实现的,集成测试(Integration Tests)和端到端测试(End to End Test),需要针对被测试对象的不同而使用不同的测试工具,如(PyTest,Selenium等等)。

这个岗位对代码能力的要求一般也不高,在公司里常常是女性员工担任。

在较大的组织(公司)里才会设置的岗位

数据库管理员 Database Administrator

顾名思义,专门创建、维护和管理数据库的人员,往往要求精通SQL(增删改查),透彻理解关系型数据库原理,甚至图数据库、非关系型数据库等等。

安全工程师 Security Engineer/DevSecOps

感觉就是特意强调了一下 Web 开发中防范和应对各种攻击和安全漏洞的方面,甚至值得专门的人员甚至团队来做这件事。

行业特化岗位

这就是我上面提到的,笼统地都可以属于「后端」,但是又不掌握「API」、「Web安全」、「框架」这些后端技能的岗位。

数据工程师 Data Engineer

通俗讲就是「搞大数据的」,用到的有Apache Hadoop,Apache Spark,还有近几年的Google BigQuery 等等。

负责搭建端到端的数据处理框架(End to End Data ETL Pipeline),这里ETL (Extract,Transform,Load)是一个常见词,不亚于后端的CRUD。又可以细分为上规模数据的批处理(Batch)和流处理(Streaming)。前者是一批数据打包处理,不要求实时性;后者是少量数据(但可能有很高的并发)的实时处理。

这方面的工具有Apache Airflow,Apache Beam,Kafka,Dataflow 等等,在不同场景下做出正确且恰当的选择。

机器学习工程师 Machine Learning Engineer

和上面提到的算法研究员不同,这给岗位不但要掌握机器学习相关的理论和知识,也要有能力搭建、部署和维护生产环境中的机器学习(或者叫AI)产品。属于后端吧,但不关注 Web 框架,也不关注 API。算是算法研究员的工程化岗位,职责不再是发论文,而是开发工程软件服务。

用到的工具、框架、包等等是各位比较熟悉的Tensorflow,Pytorch,Scikit-Learn等等。

机器学习运维工程师 MLOps

鉴于机器学习领域具有一些特殊性,这类产品的开发和部署流程需要在工程领域做出特殊处理。比如合适重新训练模型,如何回滚、管理、维护这些模型,如何管理特征工程中用到的特征,如何更新这些特征等等。

这个岗位比机器学习工程师更工程化,关注的点也从机器学习本身变成了机器学习产品的开发和部署工作流。

这方面的概念、工具、框架主要有Kubeflow (那当然也得提一下 Kubernetes 了),容器化(Docker,image,container等等),Apache Airflow,Tensorflow Extended,H2O 等等。

学校里学的知识

相关专业的同学在找工作的时候往往会遇到一种「不匹配」的感觉,不知道自己学的东西和要找的工作之间有什么关系。

要知道,上面提到的一些岗位,甚至是课堂中一笔带过甚至完全不讲的领域:比如运维。相信各位见过不少讲授某门编程语言课程但自己甚至都不会使用现代 IDE 的老师。

在学校里,首先大家要学的是通识课,其中以数学、物理、英语为代表。接下来会学一些比较难、比较基础,很难直接发现有什么用的课程,比如计算机组成原理、计算机网络、编译原理等等。再接下来会学一些很难,似乎很有用的课程,比如数据结构、算法,概率论、数理统计、凸优化等等。这个过程中也可能会接触一些「应用」类的课程,比如C程序设计、面向对象编程、数据库原理等等。

这里面有一个误解,同学们倾向于用「Java」来代指面向对象编程这门课,虽然Java确实可能是这门课的载体,考试和大作业也是围绕Java展开的,但这么代指就可能会带着你思考的方向偏离面向对象的原理,而聚焦于这个原理在Java中的呈现:具体的语法、具体的实现、具体的某种设计模式等等。同样的,如果用Python来指代数据处理这门课(如果有的话)想必也是有偏颇的,毕竟用Excel、Matlab也都可以处理数据。

找工作的时候,看到眼花缭乱的岗位和职责描述,大家很容易有这种感觉:怎么公司要求应聘者掌握的技能我见都没见过(比如什么是SpringBoot?),为什么我学的东西几乎在这些职责描述中看不见(除了在要求候选者掌握的技能里能看到一些编程语言和课程名称之外)?

等到工作一段时间以后更会发现,那些在学校里所谓「应用」类的,不怎么被重视的东西,才是自己安身立命的本钱,甚至要不断学习新的应用技能。而这类岗位也是最多的。

但再过一段时间就会发现,尽管通过刷题可以呈现出一种掌握了算法(不是指机器学习算法)和数据结构的错觉,但真正理解和掌握算法和数据结构是更高级技术岗位的基石。这里的高级并不代表职场晋升之路,仅仅是从从事的业务类型、难度和对应的经济回报而言。

而头部岗位,要求的东西会更基本,到了编译原理、计算机组成原理、计算机网络,甚至统计学和数学的级别。这类岗位是更稀少的。想象一下登月工程的程序员,在极其有限的硬件条件和网络条件下,如何设计程序、编写代码。阿波罗工程的部分代码已经在Github上开源了,不妨去看看。

写在最后

写下此文的一个动机是我个人的不满情绪。作为一个学习了部分编程知识,主要时间投入在机器学习算法方面的人,虽然可以做一些编程的工作(见上文中传统软件开发部分),但更希望自己的岗位是机器学习领域的特化岗位,偏工程化的大数据也好;但绝对不希望看到这样的要求:既然你懂Python,那么你去给我写这个API,3天够不够?

这里面包含着极大的误解和不尊重,也让我意识到了从我的角度和从传统软件开发业界的角度来看,对「编程工作」的理解有多大的差异。

意识到这个思维框架(或者叫知识树?)的存在以后,我发现网上相关的讨论也颇有这种「鸡同鸭讲」的美感。写下此文,了自己的一个心结,也希望对大家有所帮助。

当然,如果你认为我讲得不对,请相信自己,你是对的。我写的只是偏见。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注