JavaEE初阶系列 -开头篇:计算机是如何工作的(为下一篇的线程做铺垫)

最后

经过日积月累, 以下是小编归纳整理的深入了解Java虚拟机文档,希望可以帮助大家过关斩将顺利通过面试。
由于整个文档比较全面,内容比较多,篇幅不允许,下面以截图方式展示 。







由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

而且 nm 这个尺度,已经是分子级别了,已经脱离了力学范围,量子力学接手!

而且 美国在芯片市场上卡中国的脖子【卡的就是CPU】

假如在读的各位中有人发明了光刻机,直接拿到共和国勋章是没有问题的。


CPU 里面除了运算器之外,还有控制单元和寄存器。

========================================================================================

寄存器


寄存器是 CPU 内部用来存储数据的组件。

访问速度:寄存器 比 内存 的 3 ~ 4 数量级。

【内存访问速度比硬盘快成千上万倍,寄存器的访问速度 又是 内存的 成千上万倍】

【寄存器的访问速度 是 硬盘的是 上亿倍!!】

相对的,寄存器的存储空间 又比 内存 小上很多很多。

现在的 x64 的 CPU(64位 CPU),大概有 几十个寄存器,每个寄存器是 8 个字节。——大概就是几百个字节。(内存现在普遍都是 8G 的。可想而知 寄存器 和 内存 的 存储空间的差距是非常大)

理由很直接,成本比内存贵很多的。

另外说一点:我们平常见到的CPU大部分都是家用的,最好的CPU (i9 12900 也就5000)。

最好的CPU 是 给 服务器用的那种,比如说 inter的志强系列。

这种CPU 贵的大概 2 ~3w。

总得来说:只要钱到位,什么都好说!


寄存器的持久化存储:与内存一样,断电后消失。


控制单元(CU)


CU 协调 CPU 来去进行工作。

CPU上已经有寄存器可以存储了,又有 运算器 进行运算,但是你还得有一个进行调用工作的“人”,它来协调这些组件进行操作。

CU 最主要的工作:能够去执行指令,然后指挥 CPU 来完成一些具体的操作。


指令 (Instruction)

首先,指令 和 我们的编程密切相关。

其次,我们先介绍下我们需要到的指令(instruction),又称机械语言。

说到机械语言,就不得不讲一下 编程语言。

编程语言大概分为三类:

机器语言(通过二进制的数字,来表示不同的操作)

【1、不同的CPU,哪怕是同一个厂商,只要型号不同,CPU 所支持的 机器语言 都可能不相同。】

【2、一个CPU到底支持哪些指令,生产厂商会给我们提供一个“芯片手册”,里面会详细介绍CPU都支持哪些指令,每个指令都是做什么的】

汇编语言 (又称助记符)

【1、每一句机械指令,都用一个单词符号去表示。于是就有了汇编语言】

【2、因为机械语言是由 0 和 1 组成的,容易眼花出错。所以汇编语言使用的是 用简单的英文来表示不同的指令。】

【3、汇编语言 和 机器语言是一对一的关系(原则上完全等价)。】

【4、不同CPU支持的机械指令不一样,自然不同CPU上的汇编也是不一样的】

(大部分学校讲的汇编语言都是针对 一款上古神U,inter 8086 CPU.这款CPU统治市场20年【197x ~ 199x】,需要注意的是当年的 8086上面的机械指令【汇编】,在现在的电脑上已经跑不起来。 )

(唯一可能接替它的只有 inter E3系列)

高级语言(C、Java、C++…)

所谓指令(机械语言),即指导 CPU 进行工作的命令主要有操作码 + 被操作数 组成

其中操作码用来表示要做什么动作被操作数是本条指令要操作的数据,可能是内存地址,也可能是寄存器编号等。

指令本身也是一个数字,用二进制形式保存在内存的某个区域中


指令是如何执行的?

下面一个最简单的构造手册,来帮助我们理解 指令是如何执行的。

指令表(Instruction Table) / 构造手册

假设我们的 CPU 现有两个寄存器: LOAD_A(寄存器A 00)、LOAD_B(寄存器B 01)

| 指令(instruction) | 功能说明 | 4位 opcode | 操作的地址或者寄存器 |

| — | — | — | — |

| LOAD_A | 从 RAM 的指定地址,将数据加载到 A 寄存器(读内存操作) | 0010 | 4 位 RAM 地址 |

| LOAD_B | 从 RAM 的指定地址,将数据加载到 B 寄存器 | 0001 | 4 位 RAM 地址 |

| STORE_A | 将数据从 A 寄存器写入RAM 的指定地址 | 0100 | 4 位 RAM 地址 |

| ADD | 计算两个指定寄存器的数据的和,并将结果放入第二个寄存器 | 1000 |        2 位的寄存器 ID               2 位的寄存器 ID |

示例1:我们现有一条指令(机器语言) : 0010 1010

这个指令的意思:就是把 1010 内存地址上的数据给读取到A寄存器中

在这里插入图片描述

示例2:指令(机器语言) : 0001 1111

在这里插入图片描述

示例3:指令(机器语言) :0100 1000

在这里插入图片描述

示例4:指令(机器语言) :1000 0100

在这里插入图片描述


拓展:如何计算 两个数相加?

在这里插入图片描述


题外话

==================================================================

虽然我们用的都是高级语言,汇编语言几乎不会用到、

但是在一些特殊领域上,就需要用到汇编,就需要理解机器指令。

比如:

1、游戏领域【外挂】

外挂是一个单独的程序,对于一个游戏来说,源代码是不会开源的。

虽然没有原码,但是可以有执行程序(后缀 exe 文件),这里面其实就是二进制的机器指令。

这些文件里面有特定的结构(Windows:PE结构,Linux: ELF)

这些结构,其中有个部分叫做代码,包含了程序涉及到一些逻辑。(二进制指令)

我们就可以通过研究这里的机器指令,找到一些关键逻辑。

比如:吃鸡的锁血外挂,就是找到中弹扣血逻辑。

修改一些机器指令的条件判定加上算术运算,或者把扣血量设置为0的操作。

其实就可以达到实现外挂的逻辑。

但是需要你 非常理解 汇编语言

2、安全领域(病毒)

外挂只是针对游戏病毒进行逆向,而病毒是针对系统的逆向。

两者的本质是一样的。


操作系统

===================================================================

首先,大家要知道 操作系统是一个“软件”。

这是计算机上最重要,也最最复杂的软件之一。

比如:

Windows、Linux、mac、Android、ios、openwt…


操作系统的作用是什么?


”操作系统作用主要就是管理,操作系统就是一个搞 “管理的软件

1、对下,要管理好各种硬件设备

2、对上、要给各种软件提供一个稳定的运行环境。

由此不难看出:操作系统 相当于 在 软件和硬件之间 建立了一座“桥梁”。

这个时候,我们的软件和硬件就可以更好的进行交互,更好的进行相互配合,更好的来完成一些共同的工作。

在这里插入图片描述

操作系统中提供的功能是非常复杂的。

重点给大家介绍,操作系统中对 “进程”这个软件资源的管理。


什么是进程/任务(Process/Task) - 上面你们随便看看,但是这里是重点(与线程有关)


进程就是跑起来的程序。

在这里插入图片描述

打开我们电脑的任务管理器

在这里插入图片描述

这一共有一百多个进程。【有些是系统创建的,有些是我们创建的】

有的朋友可能现在会有疑问:我们经常听说的线程又是什么?

线程 其实是 进程的一部分。(进程包含线程)

如果我们把进程想象成一个工厂,那么线程就是工厂里的流水线。

一个工厂里可以有一个生产线,也可以有多个生产线。(多线程)

【这里不多说,在下一篇多线程中,我会仔细介绍】

既然进程是一个跑起来的应用程序,这就和我们的代码怪上钩了。

我们写的代码,最终目的都是要跑起来,最终都是要成为一些进程。

对于 Java代码来说,最终都是通过 java 进程来跑起来的。

此处的这个 Java 进程,其实就是 我们平常说的JVM


操作系统是如何管理进程的?


前面我们也看到了 作者的电脑 有一百多个进程,那么操作系统又是如何进行管理的呢?


1、先描述一个进程。

明确出一个进程上面的一些相关属性。

就比如:形容一个学校的学生,你需要学校姓名,班级、专业等等


2、再组织若干个进程

使用一些数据结构,把很多描述进程的信息放在一起,方便进行增删改查。

那上面的例子来说:就是把一个学校的学生信息都列举出来。


详解

操作系统里面的主要都是通过 C/C++ 来实现的。

进程的描述,其实就是用的 C语言中的“结构体”

java的类与其差不多。

结构体 和 java的类 都是 编程语言中提供的 自定义类型。

不同的是 结构体 功能更简单。【只有包含一些成员变量,不能包含方法。也没有继承、封装这些】

类的功能很丰富【属性,方法,继承,封装,多态,反射等。。。】

操作系统 中 描述 进程的这个结构体,被称为 “PCB”(process control block - 进程控制块)

注意!这里的 PCB 不是 硬件的 那个 PCB板!而是进程控制块。


组织若干个进程:典型的实现,就是使用双向链表来把每个进程的PCB给串起来。

因为操作系统的类型是很多的,内部实现也是各有不同。所以我们此处讨论的情况就是以 linux 系统为例。

至于为什么不说Windows系统,是因为它不是开源的。我们无法得知它底层代码的程序是什么情况。

而linux 是开源的,我们是可以看到底层代码 对于 组织进程 是怎么实现的。

linux对于 组织进程的方式 就是 使用 双向链表 来把每个进程的PCB给串起来。

进一步详细的说:

所谓的“创建进程”,就是先 创建出 PCB,然后把 PCB 加到双向链表中。

所谓的“销毁进程”,就是找到链表上的PCB,并且从链表上移除。

所谓的“查看任务管理器”,就是遍历链表,依次取出 链表的每个PCB,再去取出相关资料。

我们的很多代码,最终都是会落在数据结构上。

所以一定要学号数据结构!


了解 PCB中的一些属性
1、pid(进程id) - 进程的身份标识

打开我们的任务管理器,你就可以看到 每个程序的 pid 了

在这里插入图片描述

这些 进程的 pid 可以说是 进程的身份证号。其目的:就是为了区分进程。


2、内存指针

内存指针:指明了这个进程执行的代码在内存的位置,以及 这个进程执行中依赖的数据都在哪里。

首先,我们要明确一件事:当 运行一个 exe 文件,此时操作系统就会把这个 exe 加载到 内存中,变成进程。(此时的进程 就和 这块内存 是 绑定在一起的,是相关联的)

其次,此时我们的内存就包含了很多东西,因为exe文件是加载到 内存中,所以 exe文件里有什么,这块内存中就有什么。

在 这个 exe文件中,就包含这 进程要执行的二进制指令。(通过编译器生成的)

同时,除了指令之外,还有一些重要的数据。

而 这些指令 与 数据 都会存入到内存中,并且是放在内存的不同区域里面。

这个时候,我们就需要进程知道 当前我们的指令是在哪一个内存区域中,要使用的数据 又存储在内存的哪一块区域中。

通过 内存指针,进程就能找到我们当前执行的指令有哪些,以及数据有哪些。


3、文件描述符表

我们的程序运行过程中,经常要和文件“打交道”。(文件是硬盘上的)

我们C语言中就讲过文件操作,java里面也有相关的文件操作,后面也会讲到。

不管是那种语言,这都是属于文件操作。既然是操作文件,那么本质上就是在操作键盘。

操作文件的步骤:

1、打开文件

2、读 / 写文件

3、关闭文件

注意,进程每一次打开一个文件,就会在文件描述符表上多增加一项。

这个文件描述符表就可以视为是一个数组,里面的每一个元素 又是一个结构体。每个结构体都对应着一个文件的相关信息。

我们的一个进程运行的过程中,要打开那些文件,和那些文件进行交互,都会被记入到 文件描述符表中数组的里面。


细节拓展

假设我们的代码没有什么打开文件的操作,就是一个打印语句 “hello Word” 的情况下,还是需要 文件描述符表的!!

一个进程只要启动,不管你代码中是否写了 打开 / 操作 文件的代码,系统都会默认打开三个文件:标准输入(System,in),标准输出(System.out),标准错误(System.err).

对应的 文件描述符表中 会创建三个表项,标准输入、标准输出、标准错误对应的下标:0、1、2。

这个文件描述符表的下标,就被称为文件描述符。


小结:如何让一个进程正常工作

看到这里,我们如果想让一个进程正常进行工作,势必会给它分配一些系统资源。

1、内存(加载exe文件到内存中,肯定是需要占用一定内存的)

2、硬盘(操作 文件)

3、CPU(执行进程上的指令)

大家一定要明确:要想让进程正常工作,操作系统必须在硬件上给这个进程 提供 一些必要的硬件资源的支持。这样才能能够保障进程的基本工作,才能够保障我们来完成这个进程需要的一些工作任务。


上面的属性是一些基础的属性,接下来的一组属性,主要是为了能够实现进程调度。

理解什么是进程调度,是我们 理解进程管理的一个重要话题。

要想理解什么是进程调度,首先我们要知道:现在的操作系统 一般都是 多任务操作系统。

多任务操作系统:一个系统同一时间,执行了很多的任务。

与之相对的就是 单任务操作系统:同一时间,只能执行了一个任务/进程。

对于 单任务操作系统,是不需要考虑调度的。

因为它同一时刻,只执行一个进程。

再看看我的电脑,它是Windows系统,就是多任务的操作系统。

同一时间有很多进程都在运行 。

在这里插入图片描述

但是呢,这里存储在一个很重要的问题:就是我的系统上任务的数量(进程的数量),有几百个(我看了我的电脑大概200个,前面还说少了)。

但是我的电脑 CPU 核数 就那么几个(4核),这么多的任务是怎么一起执行的呢?

这件事请就是所谓的“进程调度”。

所谓的“进程调度”:就是让有限的核心,能够同时执行很多很多的任务。

关于 让有限的核心能够同时执行很多很多的任务。

这里我们需要进一步的理解一组知识点:并发 和 并行。(在MySQL中讲事务的隔离性的时候,浅显的讲了一下)

所谓的并行 和 并发,

并行:从微观上来看,两个CPU核心,同时执行两个任务的代码。

并发:从微观上来看。一格CPU 核心,先执行一会 任务1,在执行一会 任务2…最后再执行 任务1。

就是执行一圈又回来了。相当于每一个任务都执行一小段逻辑,立刻切换到下一个任务,再执行一小段逻辑,依次进行快速切换,只要切换的够快,那么从宏观上看起来,就好像这么多任务在同时执行一样。

从宏观出发:并行 和 并发 都是 同时执行两个任务。

从微观出发:

并行:多个核心 执行 多个任务

并发:单个核心 按照串行的方式 执行多个任务,但是只要它切换的足够快,从宏观来看就好像是多个任务在同时执行一样。

其实从宏观出发:

并行 和 并发 这两件事,只是在微观上有区别,在宏观上没有区别,也区分不了。

微观上的区别 都是操作系统自行调度的结果。

就比如说:我的电脑现在是 4 核,同时跑 20 个 任务。

其实这些任务中,有些是并行的关系,有些是并发的关系。

并且 可能 任务 A 和 任务 B 上一秒是并行的关系,下一秒就成并发的关系。(两者的关系是不稳定的,是会改变的)

这些情况都是微观上操作系统在控制的。

在宏观上是看不出来是 并发,还是并行的关系!

正是因为 在 宏观上区分不了并发和并行,所以我们在写代码的时候也不去具体区分这两个词。

实际上通常使用 “并发” 这个词,来代指 并行 和 并发。

咱们只是在研究操作系统的进程调度这个话题上,稍作区分。(就是讲一下)

但是在其他场景中,基本都是使用 “并发” 作为一个统称 来代替的。

相信大家都听说过这样的一个词:并发编程

此处的并发,就是包含了 “并发” 和 “并行”的统称。

讲到这里,其实所谓 进程调度 :让有限的CPU核数,去执行更多的任务。

关键就在于它切换的速度。其实它切换的速度是非常快的!

我电脑主频就是 2.8GHz,一秒可以执行28亿条件指令。(细品)

所以我们人是感受不到 进程之间 是否在切换的。

所谓的调度:就是“时间管理”。

举一个简单粗暴的例子(本故事纯属虚构,我要声明作者我是一个非常正直的人!但是操作系统不是,它无时不刻进行着渣男的行为)

假设作者是帅的一塌糊涂的美男子,身材还好。。

这就导致作者有被很多妹子追求。

原则上来说:同一时刻,我只能谈一个女朋友。

我希望未来的女朋友:贤惠,有钱、肤白貌美。(站在现实生活的角度,作者还没有见过这样的人)

然而身边的追求者,不存在这样的人。

因此,我就同时谈3个女朋友(3个进程/任务),来集齐上述理想女友的所有特点。(三个任务同时执行)

A:有钱,长得一言难尽

B:贤惠:非常贴心,多的不说。

C:肤白貌美:美若天仙,就是有点脾气、

集合三人的特点,我将拥有完美的体验。

但显然不科学,为此我需要合理的安排时间。

避免同一时刻,这三个人碰面。只要不碰面,就是安全的。

在这个前提,我就能将这种状态为此下去。

名副其实的时间管理大师。

怎么样去管理时间呢?

制作一个时间表

周一:和A 去逛街

周二:和 B 去图书馆

周三:和 C 去看电影

周四…

每个人依次安排一个具体的时间,通过这样的一张时间表,合理的去管理。

从宏观角度来说:我同时谈了3个女朋友。

从微观角度来说:同一时刻,我只是和 一个女朋友 在一起。

这个就是并发。

所以现在我通过这样的一张时间表,就把这些女朋友很好的进行一个“调度”。

规划时间表的过程,也就是“调度”的过程


4、状态

这个状态,就描述了当前这个进程接下来该怎么去调度。

我们只讲Linux中的种状态 :

1、就绪状态

2、阻塞状态 / 睡眠状态,暂时不可以去CPU 上执行。

Linux中的进程状态还有很多其他的。。。

正常情况下,这A、B、C 三个人随叫随到。【就绪状态】

假设:

A 要要出差一个月,显然A是不能随叫随到的。【A 处于一个 阻塞状态 / 睡眠状态】

对于处于这种状态的进程,就暂时不进行调度。(不将A排入到时间表上)


5、优先级

当我们有很多任务的时候:先给谁分配时间,后给谁分配时间;以及给谁分的多,给谁分的少。

任务之间,有的任务优先级很高,有的优先级很低。

针对 A、B、C三个人,最喜欢 B,其次是 C,最后是A。

我在安排时间表的时候,就会优先给 B 排,其次给C,最后给A。

周一 至 周三,都给B在一起。

周四 至 周五, 和 C 在一起

周六,和 A 在一起

周日:给自己放假

关于这一点,操作系统 给 进程 分配时间也是类似的。

有的进程优先级高,有的进程优先级低。

它们所受到的待遇是不同的。


6、记账信息

统计了每个进程,都分别被执行了多久,分别都执行了那些指令。

分别都排队等了多久了…

记账信息 主要是给 “进程调度” 提供指导依据。

如果长此以往,和 A 在一起的时间太少了, A对我的好感度就会降低。

这个时候,她舔的也不卖力了。我感觉我快要失去这个“钱包”了。

这个时候可以根据之前本子上安排的这个时间,就能发现给A安排的时间太少了。

接下来就适当的给她一点甜头。(头上长出犄角)

唤醒A的好感度。

放在进程中,就是不能对某个进程太冷落,导致它一直占用不了CPU。

所以我们就可以根据记账信息来灵活调整调整我们的一个分配策略。

故:得先记账。先去统计好这里面每个进程当前所吃的资源,然后再根据这里面的统计结果,来去对那些分配特别少,特别不均衡的进程,再去做出一些补偿。


7、上下文

表示 上次进程被调度出 CPU 的时候,当时程序的执行状态。

下次 进程 入 CPU的时候,就可以恢复之前的状态,然后继续往下执行。

换个经典的说法:上下文的作用就是 存档 和 读档。

用单机游戏来表示的话:存档存储的游戏信息,就称为“上下文”。

当进程 被调出 CPU 之前,要先把 CPU中所有的寄存器中的数据都给保存到内存中【PCB 的 上下文字段中】 想相当于存档了。

下次进程再被调度上CPU的时候,就可以从刚才的内存中 来 恢复 这些数据 到 寄存器中。就相当于读档。

某一天,A给我说,下个月带我前言夏威夷度假。

让我准备准备,

紧接着的下一天,B 和 我说,下周,她外婆过生日,叫我准备点礼物。

&ensp

过几天后,

A 和我 提起度假的事,问我准备的怎么样?

我说 :“礼物买好了。”

A 说 :“礼物,什么礼物?”

【这不就穿帮了嘛!】

A 说 的 度假准备好了吗?

而 我们回答的却是 B 说的 礼物准备好了。

很显然 A 和 B 的 准备 是 截然不同的。

怎么区分开?

很简单,用小本本记着。(PCB 的上下文字段)

因此,我作为时间管理大师 是有 记录日记的好习惯。

于是,我就把每次约会的重要信息记录下来。

然后,下次再和她们在见面的时候,都能对上号,哪怕时间长一点也没有关系。

通过这样的方式,我们就可以记录上次约会所达成的状态,下次再约会的时候,就可以接着上回继续往下进行了。

这样的操作就被称为 “上下文”。


拓展

进程的调度,其实就是 操作系统在考虑 CPU 资源如何给各个进程分配。

除了CPU还有其它的资源,典型的就是:内存资源又是如何分配的呢?

这就引出了我们下一个很重要的话题 :虚拟地址空间。

由于某个进程,出现了bug,导致该进程崩溃了,那么是否会影响到其它进程呢?

答案:现代的操作系统(Windows、linux、mac…)发生单个进程崩溃的情况下,其它进程是不会受到影响的。

能够做到这一点,就是“进程的独立性”来保证的。【其实是依仗了“虚拟地址空间”】

在这里插入图片描述

总结:进程与进程之间,为了保证系统的稳定性 是 隔离开的。

每个进程之间有着各自的虚拟地址空间。

彼此之间互不干扰,互不影响,就可以保证基本的稳定性。

但是!不能完全隔离,彼此之间还是需要交互的。

但是为了保证进程安全,又需要对交互做出限制。

于是就提供了 进程间通信 机制,通过“公共空间”进行交互。(进程A 先将数据放入公共空间,进程B随后再去取,这样就完成了进程之间的交互)

 

另外,其实在操作系统中提供的“公共空间”有很多种。

并且各有特点:有的存储空间大,有的存储空间小,有的读取速度慢,有的读取速度快…

就是说:操作系统中提供了 多种 这样的 进程间通信 机制。

(其中有些机制,已经是被淘汰了的,所以我们就不去考古了)

**现在最主要使用的 进程间通信 方式,有两种:

1、文件操作

2、网络操作(socket)**

linux 系统 还另外提供了 :管道、消息队列、共享内存这些东西。

这些东西也是 进程间通信 机制,但是也是属于不常用的机制。


重点部分总结

=====================================================================

1、 进程是什么?


感受:

其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。

特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。

也祝愿各位同学,都能找到自己心动的offer。

分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档

拿到字节跳动offer后,简历被阿里捞了起来,二面迎来了P9"盘问"

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

就是说:操作系统中提供了 多种 这样的 进程间通信 机制。

(其中有些机制,已经是被淘汰了的,所以我们就不去考古了)

**现在最主要使用的 进程间通信 方式,有两种:

1、文件操作

2、网络操作(socket)**

linux 系统 还另外提供了 :管道、消息队列、共享内存这些东西。

这些东西也是 进程间通信 机制,但是也是属于不常用的机制。


重点部分总结

=====================================================================

1、 进程是什么?


感受:

其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。

特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。

也祝愿各位同学,都能找到自己心动的offer。

分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档

[外链图片转存中…(img-PKW3M5sL-1715289727623)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 24
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值