个人主页:个人主页

系列专栏:C/C++基础与进阶

推荐一款模拟面试、刷题神器,从基础到大厂面试题点击跳转刷题网站进行注册学习

目录

1、概述

2、C++的地位与应用领域

3、常见的C++岗位都有哪些?

3.1、Windows/国产化客户端软件开发

3.2、通信协议开发

3.3、音视频编解码开发

3.4、网络组件开发

3.5、公用开源组件及安全组件开发

3.6、业务组件开发

3.7、服务器侧业务软件开发

3.8、服务器侧开源组件开发

3.9、数据库开发

3.10、算法开发

4、如何提升个人的技术竞争力?

5、C++客户端开发

5.1、国产化操作系统和国产化CPU

5.2、客户端UI技术


最近看到大家在讨论C++开发语言的学习价值与发展前景,今天作为C/C++软件开发的多年从业者,来谈谈我的理解和认识,给大家提供一个借鉴和参考。

VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新…)C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新…)

近些年随着移动互联网的兴起与普及,移动APP遍布于我们日常生活的每个角落,移动APP的开发变得火热起来,作为安卓APP开发语言的Java又被注入了新的活力。并且随着大数据与云计算技术的广泛应用,作为大数据技术框架编程语言的Java,其地位又得到了进一步的加持。Java得益于其良好的开源生态,技术更新迭代很快,近年来又推出了基于Java的云原生与微服务的新技术,这进一步提升了Java的火热程度。此外,Web前端技术的发展势头也比较迅猛,Go、Rust等新兴的编程语言也得到了广泛的应用与普及。只专注于语言标准推进的C/C++,没有开源生态与开源社区的支持,显得落寞了不少,部分细分领域已逐渐被Go、Rust等新兴语言抢占。

这些年互联网的发展异常的火热,蓬勃发展的大数据与云计算技术,炙手可热的云原生与微服务技术,使得大家都把眼光聚集到与这些技术紧密相关的Web前端及Java后端开发上。这也引发了一个趋势,各大院校计算机专业的学生在选择学习及发展方向时大多数都选择了Web前端或者Java开发。

这其中还有一个很重要的原因是,因为C++语言标准的臃肿与复杂的语言特性(指针与内存管理等),让很多人望而却步。学习C/C++的人变得越来越少了,这给C++岗位的招聘带来了很大的影响。现在公司想招聘一个C++岗位的人,无论是社招还是校园招聘,都比前些年要难一些了。

此外,还有一个比较普遍的现象,从从业多年的身边情况来看,很多从事C++开发的人员都不是计算机科班毕业的,都是从其他工科专业跨界转过来的。

我本人就是学自动化专业的,硬件不懂,毕业后只能选择软件方面的工作,在校期间自学一些C++方面的基础内容,毕业后就跨界进入了软件开发行业。

为什么非计算机专业的学生,大多都选择了C++方向呢?其实很简单,非计算机的工科专业都会学习C语言程序设计这门课,所以接触到的基本是C/C++方面的内容,对于考研的工科类同学,接触C/C++的也比较多,所以很多人毕业了都选择从事C/C++开发的相关的工作了。硬件的门槛比较高,学习硬件或者从事硬件研究的学生比较少,所以大部门工科毕业的学生都去从事软件相关的工作了。

2、C++的地位与应用领域

C++作为一门偏底层的高级编程语言,诞生的比较早,在多个领域有着广泛而成熟的应用。虽然近些年受到了Java及Go、Rust等新兴语言的冲击,但其仍然保持着旺盛的生命力,牢牢占据着世界编程语言排行榜的前几位。

C和C++在执行效率上是最接近汇编语言的高级编程语言,在许多对代码执行效率有很高要求的场景中会优先考虑使用C++。除了一些传统的应用领域,在对运行性能要求很高的人工智能、机器学习、计算机视觉与图像识别、自动驾驶等新兴技术领域,都在使用C++去做大量的开发工作。随着技术的不断发展,C++的应用场景也在不断地扩展延伸,特别是在物联网和云宇宙领域。

作为软件工业基础之一的C++,从当前的活跃程度及应用现状来看,是有广泛的用武之地的,是不会退出历史舞台的。C++虽然没有Java那样繁荣的开源社区和通用的开源框架,但C++也有庞大的开源技术与功能体系,一个大型的商业化系统总是离不开C++的,后台的多个业务模块都是用C++开发实现,也会大量地使用多种C++开源库。

从C++开源库ACE和boost在高性能通信领域的应用,以及MTL这样的高效数值计算开源库在数值计算领域的出色表现,我们可以看到C++在高性能应用场合下的不可替代的作用,而嵌入式系统这样内存受限的平台,C++已经发挥着并且将发挥更大的作用。 可以预见的是,无论以后上层应用软件怎么变,它的底层核心都会是由C/C++这种高效率的编程语言实现的,比如Java虚拟机、微软的.NET Framwork框架。因为只有这样的高效率编程语言才能完全彻底地发挥机器的功能。

对代码的执行效率和速度有很高的要求的场景会选择使用C++,从当前的现状来看,使用C++的主要领域有:

1)算法领域

常见的算法有路由算法、搜索算法、图像识别算法、语音识别算法、音视频编解码算法、广告推荐算法、内容推荐算法等。这些算法代码可能会比较冗长复杂,可能会被频繁的调用和执行,要及时地给出分析结果,所以对代码的运行速度的有很高的要求,这些算法一般都会使用C++去实现。

2)人工智能与计算机视觉领域

人工智能现在是最火热的一个发展方向之一。这里面有两个典型的应用,一是图像识别与图像处理,二是语音识别,这些场景对实时性要求比较高,实现时会使用到大量的算法,所以一般也会选择使用C++去实现。

3)后台服务器领域

一个完整的大型软件系统,从前端到后台会使用到多种开发语言,出于效率考虑,后台的很多业务服务器会使用C++开发。后台服务器程序一般是运行在Linux系统中的(服务器一般会选用Linux系统作为其操作系统),所以主要是进行Linux系统上的C++开发。

4)游戏领域

很多大型桌面端的游戏客户端及后台服务器都是C++开发的,客户端会使用C++加专用的游戏渲染引擎去开发游戏界面。

5)VR/AR虚拟现实与增强现实领域

这也是最近几年发展起来的一个热门领域,是计算机图形学、多媒体技术、传感技术、网络技术等多种技术的集合,包含了多媒体、三维建模、实时视频显示及控制、多传感器融合、实时跟踪及注册、场景融合等新技术与新手段。VR/AR在数字地球、数字城市、虚拟地理环境中有着广泛的应用。

6)汽车无人驾驶领域

汽车领域的无人驾驶也是发展势头强劲的一门高尖端技术,它是传感器、计算机、人工智能、通信、导航定位、模式识别、机器视觉、智能控制等多门前沿学科的综合体。目前百度是无人驾驶领域的佼佼者,华为紧随其后。除了这两家头部公司之外,很多车企也开始在该领域有所布局,比如大众旗下就有专门研究无人驾驶技术的子公司,我们有同事现在就在那边做,主要使用C++。

7)音视频编解码领域

音视频编解码一方面是控制摄像头采集图像,并对图像进行编码,另一方面对收到的远端图像进行解码显示,这些编解码的控制代码基本都是用C++实现的,这其中会使用到音视频编解码算法基本是用C实现的。在音视频编解码领域有很多知名的开源库,比如ffmpeg、webrtc、live555、SDL等。

除了上述领域,其实还有嵌入式领域、物联网开发领域等,这里就不展开介绍了。

此外,有时甚至为了提高代码的执行速度会在源码中直接嵌入一段汇编代码,甚至整个函数都用汇编代码去实现,这在音视频编解码模块的代码中是很常见的。

有人可能会问,经过IDE编译出来的二进制文件中也都是汇编指令,你人为的添加一段汇编代码,都是汇编代码,为啥会有执行速度上的差别呢?因为源代码经过编译器的处理生成的汇编代码在实现上可能不是最优的,这要依赖于通用的编译器,而我们人为添加的汇编代码,编译器不会做任何修改,所以我们可以直接在汇编代码中直接去控制操作,保证汇编代码是最优的,不再依赖编译器去生成。

3、常见的C++岗位都有哪些?

在IT行业里,C++相关岗位一般有Windows/国产化客户端软件开发、通信协议开发、音视频编解码开发(非算法类)、网络模块开发、公用开源组件及安全组件开发、业务组件开发、服务器侧业务软件开发、数据库开发、服务器侧开源组件开发、算法开发等。当然还有其他的一些细分岗位,我们此处只大概地说一下这些常见的岗位。

3.1、Windows/国产化客户端软件开发

该岗位主要开发客户端UI软件,一方面要将数据在UI上展现出来,另一方面要在UI界面上做一些业务操作。该开发岗位需要会使用常用的UI界面库进行软件界面的开发,还要对软件业务有一定的了解。现在正在大力推行国产化进程,所以很多厂商纪要开发支持Windows系统的软件,也要开发支持国产化Linux操作系统的软件。此类岗位的门槛较低,一个刚毕业的新手,经过几个月的熟悉与学习就能很快上手,很多代码的实现细节都可以在网上找到,很多交互场景及用法都有迹可循。

该岗位的门槛不高,较容易被新人替代,还是要尽可能地多去涉足一些有深度有难度的问题及领域,掌握一些一般人不具备的技能和经验,使自己变得更加全面更有价值,这样就不容易被取代了。

3.2、通信协议开发

该岗位主要开发维护一些标准的或者自定义的通信协议,比如大家熟知的SIP协议、GPRS协议以及一些移动通信领域的协议。有可能也需要去封装和维护一些通用的http/https、websocket等开源协议库。

该岗位会涉及到Socket网络通信、协议协商与通信的详细细节,有一定的专业深度和门槛。

3.3、音视频编解码开发

该岗位主要是使用音视频编解码算法库去控制音视频的采集编码、音视频码流的解码播放显示。该岗位一般不会去开发具体的音视频编解码算法,算法则由专门的算法工程师去开发维护。该类开发人员会时常和大名鼎鼎的开源音视频库打交道,比如ffmpeg库、webrtc库、live555库、VLC播放器、SDL等,会使用到开源库中的一些功能模块。

做音视频编解码开发的人员相对其他岗位不是很多,主要集中在做视频会议、视频监控、在线视频、短视频、直播、图像检测与识别、音视频解决方案(比如声网)的这些公司中。此类开发人员专业性比较强,在招聘市场上相对较紧缺一点,也比较受欢迎。

3.4、网络组件开发

该岗位主要从事供各个业务单元通信的公用网络模块的开发,即处理Socket网络编程相关的事务。可能会用到一些网络通信的开源库,比如ACE、Boost等。搞Socket网络编程,要处理Socket网络通信过程中的各种网络异常,需要对TCPIP协议栈有一定的了解,要掌握一些常用的网络知识,要会使用Wireshark抓包分析各种网络故障。

这类岗位一般专业也相对强一些,现在的软件系统都是通过网络和远端的服务器进行远程通信的,网络通信模块是必不可少的。

3.5、公用开源组件及安全组件开发

该岗位主要是维护一些公用的开源组件和安全组件,对开源组件进行封装,排查开源代码中存在的问题。C++诞生的时间比较长,有庞大的开源体系,有实现各种功能的开源库,特别是一些国外顶级的IT公司开发了大量的开源库,比如google。

很多开源库一般都支持跨平台,代码编写的很复杂,会使用到各种新的C++标准中的内容,阅读起来有较大的难度,维护也有较大的难度。开源库很好用,但开源库一旦出问题,则比较难查。大型IT公司和互联网大厂,都在大量的使用开源库,他们也有大量的高级专家去处理开源库的相关事务,解决开源库使用过程中遇到的问题。

该岗位会频繁地和开源库打交道,可以学到开源库中优秀的设计思想和实现机制,专业性也比较强。

3.6、业务组件开发

该岗位是将底层的协议模块、音视频编解码模块、网络模块、公用组件集成在一起去完成相关业务的控制与开发,要负责和远端的服务器进行数据通信。业务组件模块主要是为上层的Windows/国产化/MAC客户端、iOS/Android移动APP、嵌入式硬终端等服务的,将这些上层应用软件的通用的业务模块或业务控制模块抽象出来,统一放到业务组件模块去处理。

该岗位的开发人员工作量会比较大,会比较辛苦,要为上层的各个形态的应用软件服务,要排查各个应用软件业务上的故障问题。因为要和远端的服务器通信,会使用到一些标准的网络通信开源库,比如http/https库、libwebsockets库,当然还会使用到私有的网络库。

3.7、服务器侧业务软件开发

该岗位是开发各个业务服务器,服务器与服务器之间要交互,又要为多个并发的客户端提供交互服务,会频繁地使用到多线程编程及多进程通信的技术。服务器要保证24小时不间断无故障的稳定运行,要为多个并发的客户端提供及时的交互服务,服务器还要做多机备份,在出现故障时要及时地将业务切换到备份服务器上。

服务器的稳定性和性能比客户端要严苛很多,服务器侧的程序会使用到大量的开源技术,技术含量也要高很多,所以搞服务器侧的C++开发要更有挑战,更有技术含量一些,更有利于个人能力的快速提升。我们有很多搞终端侧的同事,都转行搞后台C++服务器开发了。

3.8、服务器侧开源组件开发

该岗位主要是维护开发各服务器交互的公用开源组件。服务器程序会大量地使用到各种开源技术,使用到的开源库也会非常负责,维护的成本也比较高,一旦开源库出问题,会比较难排查。

3.9、数据库开发

该岗位主要处理平台侧数据中心的数据存储与查询事务。在有的小的系统或公司中,可能没有的专门的数据库开发工程师,这些数据库事务都被服务器业务开发工程师代劳了。在大型IT公司和互联网大厂,因为会涉及到海量数据的存储与查询,对数据的存储与查询性能有着很高的要求,他们会有专门的数据库工程师去处理数据存储及数据查询的效率问题。

3.10、算法开发

该岗位主要开发实现各种算法。常见的算法路由算法(内置于网络设备中的)、搜索算法、图像识别算法、语音识别算法、音视频编解码算法、广告推荐算法、内容推荐算法以及一些人工智能算法等。算法类的岗位要求比较高,门槛也比其他岗位的要求高很多。

上面只是大概地说了一下C++相关岗位的情况,如果要详细了解岗位对技术能力的具体要求,可以到招聘网站上查看这些岗位的详细说明。

4、如何提升个人的技术竞争力?

技术总是在不断地向前发展,每个行业每个技术岗位都有被别人替代的风险,不同性质的岗位被替代的程度可能会有所不同。为了降低被替代的风险,需要我们不断提升自身的技术水平和能力,要在岗位上体现出一般人不具备的作用和价值。

要敢于主动地去研究和解决各种难解的疑难杂症,在分析和解决问题的过程中,能学到平时学不到的东西和经验。此外,还要积极主动地参与到相关模块的重构与性能优化任务中。不要将眼光局限在当前自己维护的模块中,在软件系统联调或者进行问题排查时,多去了解相关模块的一些技术实现细节和内容,要下意识地去捕获这些学习的机会,善于去发掘这些机会,不仅能扩充眼界和知识面,还能积累不同场景下问题的排查经验。

要敢于去研究一般人不愿去深入研究的技术,深入进去并吃透相关的技术细节,这样才能搞定一般人搞不定的问题,这样才能体现出不一样的作用与价值。

5、C++客户端开发

我们日常工作学习使用的都是Windows桌面系统,会频繁地使用到各式各样的客户端软件,所以我们重点介绍一下用C++开发客户端软件的一些内容。此外,很多C++初学者是从客户端UI界面编程开始学起的,所以有必要说一下这方面的内容。

在Windows系统中,大多数客户端都是用C++开发的,当然也有使用C#等语言开发实现的。我们日常使用的Windows桌面版的QQ、微信、腾讯会议、企业微信、字节飞书、阿里钉钉和百度网盘客户端等客户端软件,都是用C++开发出来的。随着国产化风潮的盛行,国产化系统上的客户端软件的开发也日趋火热起来,很多主流的软件都提供了支持国产化系统的客户端版本,比如WPS、QQ、微信等。

5.1、国产化操作系统和国产化CPU

目前国家正在大力推行国产化,在多个行业中施行国产化替代,国产化步伐在持续推进中。所以我们有必要介绍一下IT领域国产化相关的内容。IT软件领域的国产化主要体现在国产化系统上,国产化系统主要看两大块,一块是国产化操作系统,一块是国产化CPU。

当前主流的国产化桌面系统有统信的UOS系统、麒麟公司的中标麒麟和银河麒麟系统、深度的Deepin系统等,这些系统均是在开源的Linux系统基础研发出来的。

当前主流的国产化桌面系统的CPU有飞腾CPU、龙芯CPU、兆芯CPU等。除了国产化桌面系统之外,还有国产化服务器系统,很多关键部门的软件项目指明要部署国产化服务器系统。

对于国产化服务器系统,除了UOS和麒麟也提供服务器操作系统之外,还有华为的欧拉服务器系统、阿里的龙蜥服务器系统、腾讯的TencentOS系统。欧拉、龙蜥和TencentOS系统都是基于开源的CentOS Linux服务器系统改进而来的。

国产化服务器CPU主要有飞腾、龙芯、海光、兆芯和华为鲲鹏等。其中,兆芯和海光使用的是受美国Intel和AMD控制的X86架构,有些项目会将这两款CPU排查在外。此外,龙芯的服务器芯片还没有大规模商业化使用,其性能目前还有待验证。所以目前国产化服务器系统的国产化CPU主要使用飞腾和华为鲲鹏,这两款CPU都是基于ARM架构的,华为鲲鹏CPU的性能要强很多。

之前测试过,在搭建我们的测试平台时,使用16核的飞腾CPU(服务器CPU的核数会有几十核到上百核,我们在测试时只启用了16核)没法将我们的服务器平台跑起来,但是用16核的华为鲲鹏CPU是可以跑起来的。

平台侧的服务器设备主要分两大类,一类是非国产化的服务器设备,比如内置Intel CPU的X86 Dell服务器(可能使用的是Intel的i系列处理器或者至强服务器专用处理器);一类是国产化的服务器设备,目前主要有搭载飞腾CPU的长城服务器、搭载华为鲲鹏CPU的泰山服务器(泰山服务器也是华为的,泰山服务器和华为鲲鹏CPU是绑定在一起的)。我们用过的一款搭载华为鲲鹏920 CPU的泰山服务器的配置是96核、内存260GB,硬盘是3TB的。

5.2、客户端UI技术

客户端软件一方面要将业务数据弄到UI界面上展现出来,另一方面要提供业务操作的入口,所以客户端软件在实现时主要包含UI界面开发和软件业务两大块。界面实现,就是根据软件的需求和UI设计师的UI设计效果去实现软件的UI界面,实现过程中需要要用到一些常用的UI界面库。

常用的C++ UI界面库主要有Visual Studio自带的MFC库,开源的基于directui思想的duilib库,支持跨平台的QT库以及Chromium浏览器的UI库,当然还有一些收费的界面库,收费的界面库不在本文的讨论之列。其中,MFC库和duilib库是基于Windows窗口设计的,只能用于Windows C++客户端软件的开发;QT是跨平台的,既能用于Windnows客户端开发,也能用于Linux客户端的开发。Windows上C++软件的开发主要使用Visual Studio开发环境,如果用到QT,一般使用专用的QT Creator开发环境。

5.2.1、MFC库

MFC是微软的IDE开发环境Visual Studio自带的界面库,原生的MFC界面比较简陋,界面效果很一般。MFC是个很古老的库,虽然Visual Studio更新了很多代,但MFC库始终维持在多年前的效果上,基本没有做任何升级和改进。

平时我们使用MFC库去开发一些小的工具软件,会很方便,不用额外的去做界面处理,直接使用MFC就完全能满足要求了。但对于一些商业软件,原生的MFC库是没法满足要求,需要继承MFC库中的控件类,重写这些控件类以实现界面的贴图美化,但要实现比较酷炫的界面效果,使用MFC去实现就会很吃力了。

现在的商业软件基本都不再使用MFC了,但有个行业除外。很多炒股类软件的客户端(比如大智慧客户端软件)还在用MFC库,炒股软件的界面主要来显示股票数据,对界面的美化效果没有太大的要求,使用MFC库做一些基本的美化即可。

5.2.2、duilib库

duilib库是基于directui思想实现的UI界面库,相对于MFC,要好用很多,可以较容易地去实现一些酷炫的界面效果。很多知名的公司都在使用该库,比如ZOOM视频会议客户端、PC版微信、爱奇艺PPS客户端、京东咚咚客户端、百度网盘客户端、酷我音乐、酷狗音乐、华为PC版手机助手等。有些中小型公司也在使用该界面库,比如2345公司的好压等产品。

网易和腾讯都开源了各自基于duilib改进而来的界面库,原生的duilib我们使用过,但腾讯和网易的开源版本没有研究过,不知道效果如何,不知道相对于原生的duilib都做了哪些改进。回头有时间的时候可以去研究一下

5.2.3、QT库

QT是一套支持跨平台的界面库,既支持Windows平台,也支持Linux平台,甚至支持移动平台。如果要开发Linux系统中的客户端软件,则需要使用QT界面库。随着国产化系统的推行与普及,很多软件既要支持在Windows上运行,也要支持在国产化Linux桌面系统上运行。

有些厂商为了实现对Windows和Linux双平台的支持,直接使用QT界面开发,而不再选择Windows用Windows专用界面库开发、Linux用QT开发的方式。比如视频监控大型厂商海康威视和大华的视频监控客户端软件都是直接采用QT界面库开发的。很多做人工智能的公司都选择QT进行应用软件的开发。

近年来在国产化大潮的推动下,QT的支持者和使用者越来越多,QT开发也变得越来越火,招聘市场上对QT开发人员的需求也越来越大,很多大公司的软件也在选择使用QT开发。QT当前的火爆场面,在几年前是不曾有过的。

5.2.4、Chromium开源浏览器的UI库

Chromium是Google的一个久负盛名的浏览器C++开源项目,它是Google的Chrome浏览器背后的引擎(几乎包含了Chrome浏览器的所有实现代码),其目的是为了创建一个安全、稳定和快速的通用浏览器。

Chromium的设计思想基于简单、高速、稳定、安全等理念,在架构上使用了Apple发展出来的WebKit渲染引擎,并采用Google独家开发出的用于提升JavaScript解译效率的V8引擎,以提升JavaScript的效率,而且设计了“沙盒”、“黑名单”、“无痕浏览”等功能,来实现稳定与安全的网页浏览环境。

很多浏览器使用的都是Chromium开源内核,比如微软Win10系统中推出的Edge浏览器抛弃了IE内核,转而使用Chromium内核。国内知名的360浏览器、QQ浏览器、傲游浏览器,它们用的都是Chromium内核,只是开发了各自的UI皮肤和界面,增加了一些额外的用户功能。接下来说到的CEF嵌入式浏览器框架也是基于Chromium内核实现的。

除了浏览器使用到了开源Chromium的内核,很多Windows应用软件也使用到了Chromium中的内容,使用到了Chromium中的UI组件。比如字节的飞书客户端、阿里的钉钉客户端、华为的WeLink客户端、网易云音乐与有道云笔记,均使用到了Chromium中的UI组件。

那如何去判断一个客户端软件是否使用了Chromium浏览器的UI组件了呢?其实很简单,可以使用Visual Studio自带的SPY++工具,去探测一下这些软件的窗口属性,如果窗口的标题和类名中看到了Chrome的字样,就基本能确定软件的界面就是用Chromium的UI组件开发的。比如下图中的Chrome Legacy Window和Chrome_RenderWidgetHostHWND字符串: