一些感想

写在开头,如果你是一个坚定选择工作的研究生,在CPP和Java之间反复跳转,那么有以下几种情况,建议你选CPP:

  1. 对CPP有强大的兴趣,且组内有成熟的方向,例如:高性能计算、音频开发等方向,可以选择。
  2. 仅仅想找一份工作,不要跟自己过不去,Java很好,尤其是后端。

博主是在模型部署里做了一年,但是由于确实不感兴趣,荒废时间后发现自己的工作上毫无优势,最终无奈学习Java的。

Java有很明确的学习路线:Java基础--->JDBC + 数据库--->Java web---> spring--->SpringCloud + Redis + 中间件巴拉巴拉。

由于博主之前在CPP上有一些学习经验,但是网上的学习路线都是针对于零基础的,这样无疑会增加学习成本,所以想要记录一下整个学习过程,给同样苦苦挣扎的人一些帮助。

在写完这个博客之后,个人认为以下几个方面可以帮助你快速了解Java和cpp的不同:JVM、接口、引用变量类型、Object类、接口与泛型。这几个是最能体现Java面向对象编程思想的。

程序运行的区别

C++的代码想要运行就需要编译,编译过程包括:预处理、编译、汇编、连接。针对不同的操作系统和CPU架构,需要特定的编译器,例如x86和arm的指令不同,那么需要的编译工具链也不同。而Java程序的.java文件通过javac编译成.class字节码文件(不是机器码),字节码由 Java 虚拟机JVM解释或JIT编译为本地机器码运行,不同操作系统和硬件平台,只要安装了对应的 JVM,就能运行这些.class.jar文件。综上,Java在可移植性上具有强大的优势。

因此,Java也被叫做解释型语言,Java源代码被编译成字节码后,需要解释这些字节码才能在计算机上运行。

JVM带来的优势

cpp想要实现什么功能,都是以调用的形式,例如调用操作系统Socket的接口、操作系统thread的接口、调用自己写的接口,且由于依赖于底层的框架和操作系统,因此cpp针对一些功能实现没有相对应的库,例如实现webserver,就需要自己实现http协议、路由分发、多线程和数据库等等,而这些在Java里只需要对应的模块就可以。根本原因是,Java的可移植性更强,使得它可以做一套统一的接口供不同的平台调用。

面向过程与面向对象

这是两个有点抽象的概念,但观察.cpp和.java的程序,一个显著的差异就是main()函数的位置,在.java程序里,main()只能定义在类里,或者说,所有代码都必须属于类。回忆一下cpp代码,.h是头文件,定义类,成员函数,成员变量等,.cpp是我们想要实现的功能。功能被拆解成了无数个子任务,最终在main()里顺序执行,这就是面向过程。Java 是“纯面向对象语言”(除了基本类型),强调“一切皆类”,所以main也必须属于某个类,即使它是程序入口点。Java将所有的函数定义为了方法(Method),方法的调用必须通过对象或者类来实现,而CPP中则可以通过直接调用。Java的接口机制使得它能够很好的对对象进行封装,Object类使得JVM的任何对象都可以被方法统一调用。

Java代码的执行方式包括两种,分别是:

执行方式 描述
解释执行 最初由 JVM 中的 解释器 一条条解释字节码指令执行(速度较慢)
即时编译(JIT, Just-In-Time Compilation) 对“热点代码”(重复调用的方法)进行 动态编译成本地机器码,大幅提升运行速度

正是这种执行方式,使得Java可以运行时多态。

Q:一个有main函数的类实例化了另一个有main函数的类,那么调用谁的main?

在.cpp里,一个main函数意味着一个可执行文件,不可能存在可执行文件调用另一个可执行文件,只能依赖操作系统再开一个进程。但是在Java里,却实现了这个,Java 允许多个类都有 public static void main(String[] args) 方法,但是程序执行时只会从你运行的那个类的main方法开始执行,其它的main不会自动调用。目前能想到的优势,大概只有调试比较方便,毕竟在一个封装好的类里加main很奇怪。

变量类型

C++的数据类型包括:基本类型、自定义类型、指针类型、引用类型。你可以指定变量在堆上还是栈上,不使用new的话,默认对象在栈上,而在堆上申请的内存需要手动释放。

在Java里,包括两种变量类型:基本类型和引用类型,除了int这种基本类型外的类、接口、数组、自定义对象(包括 String、List、自定义类等)全是引用类型,只有你new出一个对象才会在堆上分配实际空间。

我们使用代码来说明两者的区别:

Myclass a;
Myclass b = a;

在C++里,上述代码会在栈区创建两个实例,sizeof(a)==sizeof(b)==sizeof(Myclass),也就是说,栈上的就是对象本身,等号进行的是赋值操作(堆操作符=的重写)。但是当Java执行这个语句之后,sizeof(a)==sizeof(b)==4/8字节,可以认为,这只是两个指针,由于没有指向具体的对象实例,所以是空。这里可以看出,Java的引用可以为空,C++不可以。

再看一个代码:

Myclass a = new Myclass();

Myclass *a = new Myclass();

上面的语句是Java在堆上实例化对象,下面语句是C++在堆上实例化对象,a都是储存在栈区的变量,指向堆上的实例。

线程调度的区别?

cpp的线程管理依赖于操作系统的API,而Java由于有自己的虚拟机,所以在操作系统的线程管理上可以再进行一次封装,所以Java通过线程池框架来对线程进行管理。CPP的优势在移动端对性能敏感的业务里更能体现,比如线程绑定核心,安卓移动应用开发使用的是JNI调用底层的C/C++接口。Java线程生命周期有六个状态,在操作系统的线程状态上对等待态进行了划分,分为:阻塞,等待,定时等待。

网络编程

我没有网络编程开发经验。。。。

维度 Java网络编程 C++网络编程
易用性 高(内置库+面向对象封装) 低(依赖系统API或第三方库)
跨平台 统一平台(JVM) 需适配多平台
性能 较高 极高
内存安全 自动管理 手动管理,需谨慎
异步支持 NIO、AIO Boost.Asio等异步库
典型应用 企业级应用、服务端 高性能服务器、底层系统

接口编程 + 多态

cpp的多态通过虚函数实现的,子类重写父类的虚函数来实现多态。而对于Java而言,实现多态有两个机制: 1. 重写父类的成员函数,不需要声明为虚函数或者接口,直接子类前面+@override即可。 2. 直接声明一个接口,而实现它的类必须重写接口。这里需要强调的是,这个接口不是父类,这种实现是重写,而不是继承。接口可以继承,一个接口可以继承另一个接口

父类中的任何函数都可以重写吗?

有限制,以下几种方法不可以重写:

  • private方法:子类无法访问父类的private方法,自然也无法重写,如果你在子类中写了同名方法,其实是一个新的方法,不是重写。

  • final方法:被final修饰的方法不能被重写,编译器会报错。

  • static方法:静态方法属于类,不属于对象,不能被重写,但可以在子类中定义一个同名的静态方法(这叫“隐藏”,不是重写)。

注意!由于Java的垃圾回收机制,所以不需要析构函数!

模板与泛型

这里体现了JVM存在的优势,cpp编译器编译出可执行文件之后,一切按照可执行文件来运行,而Java则是在编译时擦除类型信息,在运行时由JVM根据对象的类型指针来知道这个对象是什么类型的,进行类型强制转化。而泛型擦除的安全,又编译器负责检查,JVM知道当前代码一定是类型安全的,只需要根据你传入的对象类型,判断实际的类型就可以了。

泛型

Java 编译器在编译时使用泛型进行类型检查和类型推导,但在编译完成后,所有的泛型类型信息都会被“擦除”。例如:

List<String> list = new ArrayList<>();
list.add("hello");
// 编译后的字节码中其实是:
List list = new ArrayList();
list.add("hello"); // 没有泛型类型

泛型类型参数会被擦除为其上界(默认为 Object),如果你写了 ,擦除后就是Number,所有泛型方法、类只会生成一份.class文件。

JVM并不需要知道泛型的类型,它只当作是Object或擦除后的上界类型来处理,依靠的是多态机制(方法分发)和强制类型转换。

模板

C++ 在模板使用时,每用一个类型实例化模板,就生成一个新的代码版本。按需实例化:遇到新类型就生成新函数/类,每个模板参数类型对应一个完整实现,生成的是普通函数/类,与泛型无区别。可以认为是,编译器帮你做了重复性的代码工作,但是在编译时,他们就是不同的类型。

java学习篇(一)—— CPP和Java的区别之基础概念的更多相关文章

  1. Java 学习(17): Java 泛型

    Java 泛型 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说将 ...

  2. Java 学习(18):Java 序列化& 网络编程& 发送邮件

    --Java 序列化 -- 网络编程 -- 发送邮件 Java 序列化 Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据.有关对象的类型的信 ...

  3. Java 学习(19):Java 多线程编程

    Java 多线程编程 Java 给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 多线程是多任务的一种特 ...

  4. Java 学习(20):Java Applet 基础 & Java 文档注释

    -- Java Applet 基础 -- Java 文档注释 Java Applet 基础 Applet 是一种 Java 程序.它一般运行在支持 Java 的 Web 浏览器内.因为它有完整的 Ja ...

  5. Java 学习(21):Java 实例

    Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 //HelloWorld.java 文件 public cla ...

  6. Java 学习(22):Java MySQL 连接

    Java MySQL 连接 本章节我们为大家介绍 Java 如何使用 使用 JDBC 连接 MySQL 数据库. Java 连接 MySQL 需要驱动包,最新版下载地址为:http://dev.mys ...

  7. 最新java学习路线:含阶段性java视频教程完整版

    最新java学习路线:带阶段性java视频教程版本 第一阶段:Java基础 学习目标: 掌握基本语法.面向对象.常用类.正则.集合.Io流.多线程.Nio.网络编程.JDK新特性.函数式编程 知识点细 ...

  8. Java 学习(1): windows java 运行& 环境配置

    Java 文件的运行 如下,创建了一个 名为"HelloWorld.java" 的 Java 文件: public class HelloWorld { public static ...

  9. Java 学习(2):java 基础概念

    Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 重载 基础语法: 一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作.以 ...

  10. Java 学习(3):java 对象和类

    目录: --- 对象 --- 类 --- 源文件的声明规则 --- Java 包 对象: 对象是类的一个实例(对象不是找个女朋友),有状态和行为.例如,一条狗是一个对象,它的状态有:颜色.名字.品种: ...

随机推荐

  1. 🎀dubbo 2.7.2 启动报错【Unsupported generic type false】排查

    1.问题现象 dubbo服务启动时抛出异常Unsupported generic type false,但不影响服务正常发布. Caused by: java.lang.IllegalArgument ...

  2. 为什么 MySQL 选择使用 B+ 树作为索引结构?

    为什么 MySQL 选择使用 B+ 树作为索引结构? MySQL 选择 B+ 树作为其索引结构的主要原因是它具有以下几个优势,这些优势使得 B+ 树非常适合用于数据库系统中的索引实现. 1. 高效的范 ...

  3. windows切换nodejs版本

    卸载之前的nodejs 第一步:下载nvm并安装 (推荐使用nvm-setup.zip) https://github.com/coreybutler/nvm-windows/releases 第二步 ...

  4. 安装debian12和win11双系统

    安装环境:微星主板,AMD CPU 5700G 使用rfues制作分别制作win启动盘(可以在i tell you下载)和debian12(清华源下载较快)启动盘 先安装windows: 主板设置U盘 ...

  5. ArcGIS拼接、镶嵌同一空间位置的不同遥感影像

      本文介绍在ArcGIS下属的ArcMap软件中,对处于同一空间位置的多幅栅格图像加以拼接.融合与叠加等操作的方法.   假如现在我们分别有以下三幅栅格图像,三者分别是独立的三个图层.第一个图层如下 ...

  6. Docker自定义镜像输出日志

    概述 本文主要解决Docker自定义镜像之后,通过docker logs命令查看不到相关日志的问题 在 Docker 中自定义镜像输出日志,通常需要确保你的应用程序将日志输出到 标准输出(stdout ...

  7. 企业级分布式MCP方案

    飞书原文档链接地址:https://ik3te1knhq.feishu.cn/wiki/D8kSwC9tFi61CMkRdd8cMxNTnpg 企业级分布式 MCP 方案 背景:现阶段 MCP Cli ...

  8. HttpServletResponse相关

    目录 返回给客户端数据:字节流和字符流 解决返回字节流和字符流乱码问题 万能解决乱码 文件下载 tomcat提供的默认下载方式 手动编写的DownloadServlet 返回给客户端数据:字节流和字符 ...

  9. django笔记(3)-数据库操作

    一:路由系统    url    1.url(r'^index/', views.index),url(r'^home/',views.Home.as_view()), 一个url对应一个函数或一个类 ...

  10. SQL 日常练习 (十八)

    也没啥, 就是入坑 sql 根本停不下来, 势必要达到所谓 "精通" 的地步. 从网上的例子也快搬运完了, 而工作中的 sql 又是万万不能外泄了. 因此想着, 该去哪里搬砖呢, ...