知识屋:更实用的电脑技术知识网站
所在位置:首页 > 科技  > Android

如果一定要在C++和JAVA中选择,是C++还是java?

发表时间:2022-03-25来源:网络

谢邀。

一、我的经历

说说我的经历,在 C++ 和 Java 之间我经历了这么几个阶段:

大学浅尝辄止地学过一段时间 Java,后来放弃开始学 C/C++;本科毕业到硕士学的都是 C++;工作以后非 C++ 开发不做,先做 C++ 客户端开发,再转 C++ 服务器开发;后来机遇巧合去了携程旅行网做 Java 开发;前年离开携程,与人合伙创业,做技术负责人,大部分核心系统用 Java 开发,只有其中一个系统用 C++ 开发;离开创业团队,拿到了阿里的 P7 offer(Java 开发岗位,未去),详情可以看这里:

7. 拿了饿了么 C++ 开发岗位的 offer(做公司定制的数据研发),也未去。

8. 目前在某独角兽公司写 Go。

二、选 C++ 还是选 Java?

作为过来人,我的建议是:

如果你是学生或有大把空余时间,那建议你把 C++ 学好,C++ 被称为程序员的九阳神功是有一定的道理的,并不是说 C++ 有多难学,而是 C++ 技术栈的学习讲究的是其背后的一系列操作系统原理,你把 C++ 学好了,就意味着你把这些背后的原理学好了,你之后再学其他任何语言和机制都轻松很多;如果你急着找工作,或者对编程没多大兴趣,只是为了糊口饭吃,那么你可以优先选 Java,甚至 Java 的八股文面经背一背,如果运气不错的话,也能找到一份不错的工作。

三、C++ 该怎么学?

C/C++ 这门语言与其他高级语言不同,它是离操作系统较近的语言。所以学好 C/C++ 体系的技术栈必须结合操作系统的运行机制来学习,通俗地说,就是你必须掌握操作系统层面的几大基础知识,他们是汇编、编译链接与运行时体系、狭义的操作系统原理、多线程、网络编程,只有这样学习,你才能学的懂、学的通透、学以致用。咱们学习 C++ 不是为了理论研究,而是付诸实践,投入生产是吧。

我这里精心整理了一份我当初学习 C/C++ 的书单,分享给你:


用一张图来概括一下 C++ 技术栈吧:

3.1 学好 C++ 语言包括 C++11/14/17 常用语法

C++ 面试关于语法部分一般会问以下一些问题,当然这些问题也是 C++ 开发必备:

在有继承关系的父子类中,构建和析构一个子类对象时,父子构造函数和析构函数的执行顺序分别是怎样的?在有继承关系的类体系中,父类的构造函数和析构函数一定要申明为 virtual 吗?如果不申明为 virtual 会怎样?什么是 C++ 多态?C++ 多态的实现原理是什么?什么是虚函数?虚函数的实现原理是什么?什么是虚表?虚表的内存结构布局如何?虚表的第一项(或第二项)是什么?菱形继承(类 D 同时继承 B 和 C,B 和 C 又继承自 A)体系下,虚表在各个类中的布局如何?如果类B和类C同时有一个成员变了m,m如何在D对象的内存地址上分布的?是否会相互覆盖?

部分同学对以上问题总是搞不清楚,但是又不知道如何学习,于是从网上找各种文章来学习,造成这块的知识非常零碎,无法构成体系,其实这与其在网上花费大量时间,不如系统地看一下侯捷老师翻译的《深度探索 C++ 对象模型》一书。

(链接:https://pan.baidu.com/s/1oshiEAV3kwitKCMXV6wKSg提取码:obni )

这本书专注于 C++ 面向对象程序设计的底层机制,包括结构式语意、临时性对象的生成、封装、继承,以及虚拟——虚拟函数和虚拟继承。这本书让你知道:一旦你能够了解底层实现模型,你的程序代码将获得多么大的效率。对于 C++ 底层机制感兴趣的读者,这是一本让你大呼过瘾的绝妙好书。

另外,时至今日,各大企业虽然项目中未必用到 C++11/14/17 常用的语言特性和类库,但是面试还是对这些有一定的要求的,常问的有:

统一的类成员初始化语法与 std::initializer_list注解标签(attributes)final/override/=default/=delete 语法auto 关键字Range-based 循环语法结构化绑定stl 容器新增的实用方法std::thread线程局部存储 thread_local线程同步原语 std::mutex、std::condition_variable 等原子操作类智能指针类std::bind/std::function

C++11/14 网上的资料已经很多了,C++17 的资料不多,重头戏还是 C++11 引入的各种实用特性,这就给读者推荐一些我读过的不错的书籍:

《深入理解 C++11:C++11 新特性解析与应用》《深入应用 C++11:代码优化与工程级应用》《C++17 完全指南》《Cpp 17 in Detail》链接: https://pan.baidu.com/s/1MfvlrH 提取码: thup

3.2 进一步提高 C++

当你学习好了 C++ 语言本身,你可以学习一下 C++ 的一些常见惯用法和高性能编码实践,这里我推荐一本经典书籍叫《提高C++性能的编程技术》,这本书详细讨论了临时对象、内存管理、继承、虚函数、内联、引用计数以及 stl 等一切有可能提升 C++ 效率的细节内容。最终,该书将c++性能提升的各种终极利器,完美地呈现在读者的面前!最关键的是,这本书非常薄,但是书中介绍的每个专题都是实战中常用的技术,强烈推荐。

链接: https://pan.baidu.com/s/1RPgJoLL_CoOt5onKwdBbdQ 提取码: to6o

3.3 C++ 工程实践

在掌握了 C++ 常用语法和语言背后的实现机制和常用惯用法后,我强烈推荐另外两本书,一本是 《C++ API 设计》 和 《大规模 C++ 程序设计》,前者从细粒度地教你在实际开发中如何设计 C++ API 接口,后者告诉你大型 C++ 程序小到单个 .h/cpp 文件如何编写,大到大型 C++ 项目如何组织的最佳实践。这两本书都是工程实践的图书,书中的技术可以实实在在地用于一线开发。

3.4 与 C/C++ 相关的必知必会知识

第一个基础知识是汇编,我们学习汇编不是一定要用汇编来写代码,就像我们学习 C/C++ 也不一定单纯为了面试和找工作。

对于 C/C++ 的同学来说,汇编是建议一定要掌握的,只有这样,你才能在书写 C++ 代码的时候,清楚地知道你的每一行C++代码背后对应着什么样的机器指令,if/for/while 等基本程序结构如何实现的,函数的返回值如何返回的,为什么整型变量的数学运算不是原子的,最终你知道如何书写代码才能做到效率最高。掌握了汇编,你可以明白,在 C++ 中,一个栈对象从构造到析构,其整个生命周期里,开发者的代码、编译器和操作系统分别做了什么。掌握了汇编,你可以理解函数调用是如何实现的,你可以理解函数的几种调用方法,为什么printf这样的函数其调用方式不能是 __stdcall,而必须是 __cdecl。掌握了汇编,你就能明白为什么一个类对象增加一个方法不会增加其实际占的内存空间。推荐的书籍是王爽老师的《汇编(第三版)》 和韩宏老师的《老码识途 从机器码到框架的系统观逆向修炼之路》

王爽《汇编(第三版)》
链接: https://pan.baidu.com/s/12j-dUDWY1o7AZ4d4Hel1aQ 提取码: fhep
《老码识途 从机器码到框架的系统观逆向修炼之路》 链接: https://pan.baidu.com/s/14VDfyQahIOsV34OleEFdng 提取码: b83j

第二个基础知识是编译、链接与运行时体系知识。作为一个开发者,要清楚地知道我们写的 C/C++ 程序是如何通过预处理、编译与链接等步骤最终变成可执行的二进制文件,操作系统如何识别一个文件为可执行文件,一个可执行文件包含什么内容,执行时如何加载到进程的地址空间,程序的每一个变量和数据位于进程地址空间的什么位置,如何引用到。一个进程的地址空间有些什么内容,各段地址分布着什么内容,为什么读写空指针或者野指针会有内存问题。一个进程如何装在各个 so 或 dll 文件的,这些文件被加载到进程地址空间的什么位置,如何被执行,数据如何被交换。

第三个基础知识是狭义的操作系统原理。这里加上“狭义”二字是因为从广义上来讲,以上所说的内容都是操作系统原理的范畴。狭义的操作系统原理这里包括操作系统如何管理进程与线程,虚拟内存与物理内存之间的对应关系,何为内存映射文件,进程之间如何通信等等。

这两者推荐的书单: 《程序员的自我修养》和 《Windows 核心编程》,尤其是《程序员的自我修养》,搞 C++ 开发不看此书,读尽 C++ 语言书也枉然!

《程序员的自我修养》
链接: https://pan.baidu.com/s/1SlBs7_0d0CGt3RAG6tH4Sg 提取码: 5qqk
《Windows 核心编程》
链接: https://pan.baidu.com/s/1Wpa2CJdl 提取码: jjcs

第四个基础知识是多线程知识。严格来说,这点已经包括在第三点之中了,我之所以将其单独列出来,是因为多线程编程是我们做应用服务最常用的技术之一。最近面试过几个学历非常好的同学,对于一个进程中如果某个线程因为内存问题而退出,是否会导致整个进程退出的问题答不好,实在不应该。多线程知识其实不难学,立足于理解与实践而不是应付面试,可以学的很好。无论是 Windows 还是 Linux 操作系统,操作系统提供的线程同步对象就那么几种,Windows 常用的有临界区(关键端)、Event、互斥体、信号量等,Linux 有互斥体、信号量、读写锁、条件变量,这些知识点学过则会,不学则不会。这些线程同步原语花上几天就能搞得清楚,大多数同学不是学不会,而是不愿意学,但是偏偏喜欢在简历上写上自己熟悉多线程编程。面试的时候,被问到条件变量的虚假唤醒机制都说不清楚,非要说自己用过条件变量。这是一些同学犯的很低级的错误,如果真用过条件变量,如果不知道虚假唤醒机制,那一定写的代码是不对的。市场上目前没有任何一本图书对以上知识形成体系的介绍,当然,我的本书填补了这一空缺,你将从本书中获得从进程与线程的关系,再到常用的线程同步原语的区别与使用场景,再到线程池以及基于生产者消费者模型的消息队列,以及对协程思想介绍的相关知识。

掌握了常见的多线程同步原语之后,接下来可以找一些带多线程的项目去学习一下,不管是否带 UI 的都行。我推荐的一种方式是,使用 gdb 或者 Visual Studio 调试器将你需要学习的多线程程序中断下来,在多线程面板,看看这个进程一共有多少个正在运行的线程,分析每个线程的作用,然后研究下这些线程在何时何地创建的,为什么需要创建新的线程。尝试爱过几个人,面对爱情你会诚实很多;尝试研究几个多线程项目,面对多线程你会熟练许多。

推荐的书单 《C++ 服务器开发精髓

第五个是网络编程,直白地说就是 Socket 编程。操作系统层面提供的 API 会在相当长的时间内保持接口不变,一旦学成,终生受用。理解和掌握常用的基础 socket API 不仅可以最大化地去定制各种网络通信框架,更不用说使用市面上流行的网络通信库了,最重要的是,它会是你排查各种网络疑难杂症坚实的技术保障。操作系统层面提供的网络模型就那么几种,无论像 Java/Go/Python 等语言如何封装,作为技术的源头,我们有什么理由不去掌握它呢?推荐的书单 《TCP/IP 网络编程》和《Linux 高性能服务器编程》 。

《TCP/IP 网络编程》
链接: https://pan.baidu.com/s/1dh97rPB7DkAq0_iAAWtOYA 提取码: b8qb
《Linux 高性能服务器编程》
链接: https://pan.baidu.com/s/1Hujkjl4dOe45g-y-7AgYVQ 提取码: 43cq

以上是基于 C++ 技术栈来说,并没有包括算法与数据结构、数据库等方面的基本功。总而言之,学习 C++ 不能只盯着 C++ 语法本身,还要熟悉 C++ 技术栈背后的一系列操作系统原理

3.5 C/C++ 如何练习

光纯粹通过看书,可能学习效果不一定好,你一定要装一个 C/C++ 语言开发工具实际去写一写 C/C++ 代码,

Windows 上我推荐学习 Visual Studio 编译、调试和运行 C/C++ 代码,以下是一些步骤:

Visual Studio 2019 启动画面新建一个工程创建一个控制台程序给控制台程序起一个名字如果学习C语言,可以将 .cpp 文件扩展名改成 .c编译项目添加程序断点启动调试学会在“监视窗口”查看运行过程中的变量名学会在“堆栈窗口”查看程序调用堆栈学会在“内存窗口”查看程序变量的内存值调试状态下,需要熟悉的一些窗口

如果你不想只用 C 语言写一些黑洞洞的命令行程序,可以看一下《Windows 程序设计(第五版)》这本书,这本书从零教你如何编写 Windows 界面程序:

链接: https://pan.baidu.com/s/1E0TD1mUxlCU3rhlOJGX9iA 提取码: c5eg

这本书是一本经典的 Windows 编程圣经,曾经伴随着近 50 万 Windows 程序员步入编程殿堂,成长为 IT 时代的技术精英,可以这么说,中国常用的 QQ、360 安全卫士的开发者都是靠这本书启蒙的。

如果你在 Linux 下使用 C 语言编写服务程序,要学会 gcc、Makefile、CMake 等工具,推荐一下 《GNU Make 手册》:

链接: https://pan.baidu.com/s/11NZs2IPi8sMZu4n8LRgttA 提取码: hcj6

和 《CMake 最佳实践》这两本书:

链接: https://pan.baidu.com/s/1flVSq6bwu0n-Y7 提取码: 44ta

编译好程序之后,你可以使用 GDB 进行调试,GDB 掌握常用命令即可,这个很容易学,实际上手操作一下,几分钟就学会了,GDB 常用命令:

GDB 常用命令

学习 GDB 推荐《Debugging with GDB》一书:

链接: https://pan.baidu.com/s/1e3toHeLo 提取码: h0d3

3.6 推荐一些不错的 C++ 开源项目

如何阅读开源项目可以看这里:

如何调试开源 C/C++ 项目的代码可以看这里:


3.6.1 Filezilla

2016 年的时候,我无意中发现我用了多年的 FTP 软件 Filezilla 竟然用 C++ 11 重写了。

Filezilla界面

FileZilla 的源码是一个德国开发者写的,其代码质量也不错,而且使用的是 C++11 写的。可以一边调试一边学习,学完后,我的 C++11 功能得到了大大增强。

不怕你笑话,我在上学的时候,曾看过 Filezilla 0.x 版本的代码,那个时候 UI 界面用的还是 MFC。

贴一下 Filezilla 的部分代码,红框标出来的部分为 C++11 的语法特性:


代码质量总体很不错。我修改了下让其可以在 Visual Studio 中调试,这样你可以一边调试一边学习。

一套源码如果能够容易编译、调试,同时其业务是容易理解的(通俗地说,就是这套代码的功能是什么的),那么才利于新手学习。

我已经将环境和依赖都配置好了,代码获取链接:

张小方:分享一款 ftp 软件 —— filezilla的源码

3.6.2. uWebSocket

uWebSocket 是一款开源的 WebSocket 库,最新版使用了大量 C++17 的语法,代码量非常少。

下载地址:

https://github.com/uNetworking/uWebSockets

我们改造了这个项目,用于我们的交易系统的行情推送服务器。

3.6.3 TeamTalk

TeamTalk 是蘑菇街开源的一款用于企业内部的即时通信工具,其代码下载地址是:

https://github.com/balloonwj/TeamTalk

3.6.4. poco 库

POCO C++ Libraries - Simplify C++ Development

poco 库是一个代码质量非常高,且文档比较丰富的 C++ 库,实现了常用的一些功能,可以根据自己的喜好挨个看。

3.6.5. FlamingIM

https://github.com/balloonwj/flamingo

我为 Flamingo 专门录制了 3 部高清技术讲解视频以方便读者学习,视频中介绍了 Flamingo 的编译和部署方法、整体架构、各个模块的技术实现细节以及如何学习Flamingo的方法,需要视频教程下载链接: 链接: https://pan.baidu.com/s/1p_dBPJ 提取码: ah6c


3.6.6. tinySTL

https://github.com/balloonwj/TinySTL


学好 C/C++ 并非一朝一夕之功,需要不断坚持加努力,一旦学成,奇妙无穷,加油!!

四、Java 该怎么学?

下文中提到的 Java 书籍,完整的书单在这里:

4.1 Java 基础知识

Java 的基础知识包括如下部分:

1. 基础语法部分

01、Java 基础语法与运行/编译环境

JRE/JDKJava 变量和字面值Java 数据类型Java 操作符Java 输入输出Java 表达式 & 语句 & 代码块Java 注释

02、Java 流程控制

Java if elseJava switch 语句Java for 循环Java while 循环Java break 语句Java continue 语句

03、Java 数组

Java 数组多维数组Java 数组复制

04、Java 面向对象

Java 类和对象Java 方法Java 方法重载Java 构造方法Java 字符串Java 访问权限Java this 关键字Java final 关键字Java 递归Java instanceof 操作符Java 继承Java 方法重写Java super 关键字抽象类 & 抽象方法Java 接口Java 多态Java 封装嵌套&内部类Java static 关键字Java 匿名内部类Java 单例Java 枚举类Java 枚举构造方法Java 枚举字符串Java 反射

05、Java 异常处理

Java 异常简介Java 异常处理Java try catchJava throw 和 throwsJava 捕获多个异常Java try-with-resourcesJava 注解Java 注解类型Java 日志Java 断言

06、Java 集合与队列

Java 集合框架Java 集合接口Java List 接口Java ArrayListJava VectorJava StackJava 队列接口Java 优先级队列Java 双端队列接口Java LinkedListJava 数组队列Java 阻塞队列接口Java ArrayBlocking LinkedBlocking Map 接口Java HashMapJava LinkedHashMapJava WeakHashMapJava EnumMapJava SortedMap 接口Java NavigableMap 接口Java TreeMapJava ConcurrentMap 接口Java ConcurrentHashMapJava Set 接口Java HashSetJava EnumSetJava LinkedHashSetJava SortedSet 接口Java NavigableSet 接口Java TreeSetJava 集合算法Java 迭代器接口Java ListIterator 接口

07、Java I/O

Java InputStreamJava OutputStreamJava FileInputStreamJava FileOutputStreamJava ByteArrayInputStreamJava ByteArrayOutputStreamJava ObjectInputStreamJava ObjectOutputStreamJava BufferedInputStreamJava BufferedOutputStreamJava PrintStreamJava ReaderJava WriterJava InputStreamReaderJava OutputStreamWriterJava FileReaderJava FileWriterJava BufferedReaderJava BufferedWriterJava StringWriterJava PrintWriter

学习 Java 基础知识推荐以下两本书:

Java核心技术卷1 基础知识》《Java核心技术卷2高级特性》既然楼主提到《Thinking In Java》这本书,那就说一下这本书,这个书出版的年代比较久远了,加上 JDK 已经更新换代很多年了,各种新的特性和接口被加进来,这本书中部分内容已经过时了,加上这本书比较厚,如果时间不是很充足,不建议使用这本书学习。

4.2. Java 并发编程(多线程)

进程与线程的区别多线程的入门类和接口线程组和线程优先级线程的状态及主要转化方法线程间的通信重排序和 happens-beforevolatilesynchronized 与锁CAS 与原子操作AQS计划任务Stream 并行计算原理Fork/Join通信工具类CopyOnWrite并发集合容器锁接口和类阻塞队列线程池原理

Java 并发编程首推《Java并发编程实战》:

另外《Java并发编程的艺术》这一本也不错。


4.3. Java 网络编程

Java网络编程》《Java网络编程精解

4.4 Java 虚拟机

无论是 Java 面试还是想成为 Java 高手或者在一些项目中进行性能调优都必须掌握的知识,一般需要掌握以下内容:

Java 内存结构堆栈垃圾回收JVM 内存区域Java 虚拟机栈class 文件字节码指令JVM 参数调优Java 对象模型HotSpot类加载机制编译和反编译反编译工具(javap)JIT虚拟机性能监控和故障处理工具(jps、jstack、jmap、jstat、jconsole、javap)

推荐的书是《深入理解Java虚拟机》,这本书现在已成了 Java 虚拟机中的经典的经典,建议从事 Java 开发的同学一定要好好看一看。

另外,《揭秘Java虚拟机——JVM设计原理与实现》这本书也不错。

4.5. Java Web

深入分析Java Web技术内幕 修订版

完整的书单在这里:

4.6 Java 框架

4.6.1. Netty

搞 Java 的如果不熟悉 Netty 框架,那很难成为高手,虽然我们平常开发基本不会直接用到 netty,但是各种框架底层基本上都用的是 Netty,学习 Netty 可以分两步走:

第一步,学会如何使用 Netty,推荐《Netty In Action》(中译名:《Netty 实战》),或者看《Netty 权威指南》,这本书也很不错。

第二步,深入研究 Netty 的源码,学习源码中各种技术,netty 的官方源码地址:

https://github.com/netty/netty

4.6.2. SSM 框架

现在 Java 的主流开发基本使用 SSM 框架,所谓 SSM 框架指的是 Spring + Spring MVC + MyBatis。

关于 SSM 的书,其实没有特别好的,可以自己搭个框架,边看边调试,或者结合一些网络实例视频来学习。tui jian

Spring面试题知识点合集SSM 实战 100 集

上文提到的完整的书单在这里:

五、注重基础的学习

需要注意的是,无论学 C++ 还是 Java,想要在技术之路走的远,一定不要疏忽数据结构算法、操作系统原理、计算机网络、设计模式、数据库等基础知识的学习。


原创不易,如果觉得有用,请给 @张小方 点个赞吧。

收藏
  • 人气文章
  • 最新文章
  • 下载排行榜
  • 热门排行榜