话说 TP-LINK 联洲的秋招提前批曾经开启很久了,6 月份就曾经开启了,并且最近曾经有人陆陆续续拿到口头 Offer 了,所以明天就来给大家介绍一下 TP-LINK 的面试流程和真题及答案解析。
秋招提前批投递地址
官网投递地址:https://hr.tp-link.com.cn/jobList
TP-LINK 面试流程
TP-LINK 整个面试流程如下:
- 技术面:两面或者是三面,一般 Offer 两面,SP Offer 三面。
- 心理评测
- 座谈会
- 签约
- 电话 OC
-
签订三方协定
面试问题
问题来源于某客,如下图所示:
问题链接:https://www.nowcoder.com/feed/main/detail/9af7b7989419489284b3cfce7aaae2bc
答案解析
1. 说一下微服务架构?
微服务是一种软件开发架构格调,用于构建简单应用程序。
它将大型应用程序拆分成一系列较小、独立的服务,每个服务专一于实现特定的业务性能。这些服务之间通过轻量级的通信机制(通常是基于 HTTP 或 RPC)进行交互,能够独立部署、扩大和治理。
微服务的次要特点包含:
- 繁多责任:每个微服务专一于执行一个明确定义的业务性能。这使得开发人员能够更容易地了解和保护服务。
- 松耦合:微服务之间是独立的,它们能够应用不同的编程语言、技术堆栈和数据存储。这种松耦合使得开发团队可能独立地开发、测试和部署各个服务。
- 独立部署:每个微服务都能够独立地部署,这意味着当对一个服务进行更改时,不须要重新部署整个应用程序。这进步了开发和公布的速度,并容许疾速迭代和灵活性。
- 弹性扩大:因为每个微服务是独立的,能够依据须要对它们进行独立的扩大。这使得应用程序可能更好地解决高负载状况,并具备更好的可伸缩性。
-
无限上下文:每个微服务保护本人的数据存储,这意味着它们能够应用不同类型的数据库或存储技术。这种隔离有助于缩小整个零碎的复杂性,并进步可靠性。
2. 微服务优缺点
微服务架构具备以下长处:
- 松耦合:微服务架构使得各个服务之间的耦合度升高,每个服务都是独立的,能够应用不同的编程语言、技术堆栈和数据存储。这样能够进步团队的自治性,各个服务能够独立开发、测试和部署。
- 可伸缩性:因为微服务是独立的,能够依据须要对每个服务进行独立的扩大。这意味着能够依据流量和负载的需要,对具体的服务进行程度扩大,进步零碎的性能和可用性。
- 独立部署:每个微服务都能够独立地部署,这样在更新或修复某个服务时,不须要重新部署整个应用程序。这样能够升高危险,并进步开发和公布的速度。
- 技术异构性:微服务架构容许不同的服务应用不同的技术和工具。这样能够抉择最适宜每个服务需要的技术,进步开发效率和灵活性。
- 易于了解和保护:微服务架构将简单的应用程序拆分为小而独立的服务,每个服务专一于一个明确定义的业务性能。这样使得代码库更易于了解和保护。
然而,微服务架构也存在一些挑战和毛病:
- 分布式系统复杂性:微服务架构中的服务是分布式的,须要解决服务间通信、数据一致性、错误处理等问题。这减少了零碎的复杂性,须要更多的设计和管理工作。
- 服务间通信开销:因为微服务架构中的服务通过网络通信进行交互,会减少肯定的提早和开销。此外,须要实现适当的通信机制和协定来确保可靠性和数据一致性。
- 运维复杂性:微服务架构中波及多个独立的服务,每个服务都须要独立进行监控、日志记录和故障排除。这减少了运维的复杂性,须要适当的工具和自动化来治理和监控服务。
-
数据一致性:因为每个微服务保护本人的数据存储,确保数据一致性变得更加艰难。在跨多个服务的业务操作中,须要采取适当的策略和技术来保证数据的一致性和完整性。
3. 负载平衡的实现算法
负载平衡是指将网络流量或工作负载调配到多个服务器或计算资源上,以进步零碎的性能、可靠性和可扩展性。在实现负载平衡时,通常会采纳以下算法:
- 轮询(Round Robin):依照轮询的形式顺次将申请分发给后端服务器。每个申请依照程序顺次调配给不同的服务器,周而复始。这种算法简略且平衡,实用于服务器性能类似且无状态的状况。
- 起码连贯(Least Connection):依据以后连接数抉择连接数起码的服务器来解决新的申请。这种算法能够无效地将负载平衡到连接数较少的服务器上,以放弃各服务器的负载绝对平衡。
- IP 哈希(IP Hash):依据客户端的 IP 地址进行哈希计算,将同一个 IP 地址的申请发送到同一个后端服务器。这样能够确保同一个客户端的申请都发送到同一台服务器上,实用于须要放弃会话一致性的场景。
- 加权轮询(Weighted Round Robin):给每个服务器调配一个权重值,依据权重值的比例来调配申请。具备较高权重的服务器会接管到更多的申请,实用于服务器性能不平衡的状况。
- 加权起码连贯(Weighted Least Connection):依据服务器的以后连接数和权重值来抉择服务器。连接数越少且权重值越高的服务器会被优先选择。
- 随机(Random):随机抉择一个后端服务器来解决申请。这种算法简略且平衡,但无奈保障每个服务器的负载统一。
- 响应工夫加权(Response Time Weighted):依据服务器的均匀响应工夫或解决工夫来调配申请。响应工夫较短的服务器会失去更多的申请,以进步零碎整体的响应速度。
这些算法能够独自应用,也能够联合应用,依据理论需要和场景进行抉择和配置。另外,古代的负载均衡器通常会联合实时监测和主动调整策略,依据服务器的负载状况动静地调整申请散发策略,以实现更智能和自适应的负载平衡。
4.Redis 集群部署形式?
Redis 集群次要有以下三种模式:
- 主从复制(Master-Slave Replication):这是最简略的 Redis 集群部署形式。在主从复制中,一个节点作为主节点(master),负责解决写操作和读操作的局部负载;而其余节点作为从节点(slaves),复制主节点的数据,并负责读操作的负载。主节点负责写操作的原始数据,而从节点通过异步复制主节点的数据来提供读操作的负载平衡和高可用性。
- 哨兵模式(Sentinel):Sentinel 模式用于提供 Redis 的高可用性。在这种部署形式中,有多个 Redis 实例,其中一个充当主节点,负责解决写操作和读操作的局部负载。同时,还有多个 Sentinel 节点,它们监控主节点的状态,并在主节点故障时主动将从节点晋升为新的主节点。这种形式能够实现故障切换和主动复原。
-
Redis Cluster 模式:Redis Cluster 是 Redis 官网提供的分布式集群解决方案。它通过分区(sharding)将数据分布在多个节点上,每个节点负责一部分数据。Redis Cluster 应用哈希槽(hash slots)来治理数据分布,并在节点故障时进行主动迁徙和重新分配。客户端能够间接连贯到任何一个节点,节点会协调数据的读写操作。
5.MySQL 主从复制?
MySQL 主从复制是一种常见的数据复制技术,用于实现 MySQL 数据库的高可用性、读写拆散和数据备份等需要。在主从复制中,有一个主数据库(Master)和一个或多个从数据库(Slaves)。
MySQL 主从复制在确保了主服务器(Master)和从服务器(Slave)网络连接失常,能够相互拜访的状况下,通过配置(次要是主服务器开启 bin log),从服务同步 bin log 的形式就能够实现主从复制了。
5.1 配置流程
主从复制的设置步骤如下:
- 配置主数据库:在主数据库上启用二进制日志,设置一个惟一的服务器 ID,并在须要复制的数据库中创立一个专门用于复制的账户。
- 配置从数据库:在从数据库上设置一个惟一的服务器 ID,并配置连贯主数据库的相干参数,如主数据库的 IP 地址、账户信息等。
- 启动主从复制:在从数据库上启动复制过程,连贯到主数据库并开始复制主数据库的数据。
一旦主从复制设置实现,主数据库上的写操作将主动复制到从数据库上,从而实现数据的同步复制。应用程序能够通过读写拆散的形式,将读操作发送到从数据库上,以进步零碎的读性能。
5.2 优缺点剖析
主从复制具备以下长处:
- 高可用性:当主数据库产生故障时,能够疾速切换到从数据库作为新的主数据库,实现故障切换,从而进步零碎的可用性。
- 读写拆散:能够将读操作散发到从数据库上,加重主数据库的负载,进步整体的读性能。
- 数据备份:从数据库能够作为主数据库的备份,用于复原数据和劫难复原。
须要留神的是,主从复制并不适用于所有的场景,它具备一些限度和注意事项,如主从提早、数据一致性、主数据库的单点故障等。因而,在应用主从复制时,须要认真思考零碎需要和架构,并进行适当的监控和保护。
6. 口头手撕快排
疾速排序是一种分治算法,它通过将一个数组分成较小的子数组,而后递归地对子数组进行排序,最初将子数组的后果合并起来,从而达到整体有序的目标。
疾速排序的实现步骤:
- 抉择一个基准元素(pivot),通常是抉择数组中的第一个元素或最初一个元素。
- 将数组分成两个子数组,小于等于基准元素的放在右边,大于基准元素的放在左边。
- 对左右两个子数组递归地利用疾速排序算法。
- 将左子数组、基准元素和右子数组合并起来,失去最终的排序后果。
以下是 Java 实现的快排根本代码:
public class QuickSort {public static void quickSort(int[] arr, int low, int high) {if (low < high) {int pivotIndex = partition(arr, low, high);
quickSort(arr, low, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, high);
}
}
private static int partition(int[] arr, int low, int high) {int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {if (arr[j] <= pivot) {
i++;
swap(arr, i, j);
}
}
swap(arr, i + 1, high);
return i + 1;
}
private static void swap(int[] arr, int i, int j) {int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {int[] arr = {5, 2, 9, 1, 7, 6, 3};
quickSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
}
7. 队列实现栈和栈实现队列
7.1 队列实现栈
队列实现栈的基本思路是应用两个队列来模仿栈的行为,通过这种形式,能够实现栈的“先进后出”(Last In First Out,LIFO)的个性。
实现思路
- 初始化两个队列,记为 queue1 和 queue2。
- 当执行 push 操作时,将元素增加到 queue1 中。
- 当执行 pop 操作时,首先将 queue1 中的元素顺次出队并入队到 queue2 中,直到 queue1 中只剩下一个元素。这个剩下的元素就是须要出栈的元素,将其移除并返回。
- 替换 queue1 和 queue2 的援用,使得 queue1 成为主队列,即 queue1 始终保持非空,而 queue2 作为辅助队列。
- top 操作则返回 queue1 中的最初一个元素,即栈顶元素。
-
empty 操作则判断 queue1 是否为空。
实现代码
import java.util.LinkedList; import java.util.Queue; public class StackUsingQueue { private Queue<Integer> queue1; private Queue<Integer> queue2; private int top; public StackUsingQueue() {queue1 = new LinkedList<>(); queue2 = new LinkedList<>();} public void push(int x) {queue1.add(x); top = x; } public int pop() {while (queue1.size() > 1) {top = queue1.remove(); queue2.add(top); } int value = queue1.remove(); Queue<Integer> temp = queue1; queue1 = queue2; queue2 = temp; return value; } public int top() {return top;} public boolean empty() {return queue1.isEmpty(); } }
7.2 栈实现队列
栈是一种后进先出(LIFO)的数据结构,而队列是一种先进先出(FIFO)的数据结构。为了实现一个队列,咱们能够应用两个栈来模仿。
实现思路
以下是应用两个栈实现队列的思路:
- 定义两个栈,别离称为 ” 输出栈 ”(input stack)和 ” 输入栈 ”(output stack)。
- 当有新元素进入队列时,将其压入输出栈。
- 当须要出队列时,如果输入栈为空,将输出栈中的所有元素弹出并顺次压入输入栈。这样,输入栈的顶部元素即为队列的第一个元素,能够出队列。如果输入栈不为空,间接弹出输入栈的顶部元素。
- 当须要获取队列的第一个元素时,执行步骤 3 中的操作,保障输入栈的顶部元素为队列的第一个元素。
这种实现形式的思路是,应用输出栈来保留新进入队列的元素,而输入栈则负责提供队列的第一个元素和出队列操作。当输入栈为空时,须要将输出栈的元素转移到输入栈中,以保障队列的程序。
实现代码
import java.util.Stack;
class MyQueue {
private Stack<Integer> stack1; // 用于入队操作
private Stack<Integer> stack2; // 用于出队操作
/** 初始化队列数据结构 */
public MyQueue() {stack1 = new Stack<>();
stack2 = new Stack<>();}
/** 入队操作 */
public void push(int x) {stack1.push(x);
}
/** 出队操作 */
public int pop() {if (stack2.isEmpty()) {
// 将 stack1 中的元素顺次弹出并压入 stack2
while (!stack1.isEmpty()) {stack2.push(stack1.pop());
}
}
return stack2.pop();}
/** 获取队头元素 */
public int peek() {if (stack2.isEmpty()) {
// 将 stack1 中的元素顺次弹出并压入 stack2
while (!stack1.isEmpty()) {stack2.push(stack1.pop());
}
}
return stack2.peek();}
/** 判断队列是否为空 */
public boolean empty() {return stack1.isEmpty() && stack2.isEmpty();}
}
public class Main {public static void main(String[] args) {MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.push(3);
System.out.println(queue.pop()); // 输入:1
System.out.println(queue.peek()); // 输入:2
System.out.println(queue.empty()); // 输入:false
}
}
8. 过程有几种状态?
过程在操作系统中能够处于以下几种状态:
- 创立(Created):过程正在被创立,但尚未开始执行。
- 就绪(Ready):过程曾经创立并调配了所有必要的资源,期待被调度器选中并调配 CPU 资源开始执行。
- 运行(Running):被调度器选中的过程正在执行,并占用 CPU 资源。
- 阻塞(Blocked):过程因为某些起因无奈继续执行,例如期待内部事件的产生(如输出 / 输入操作)或期待资源的开释。在此状态下,过程临时进行执行,直到满足某些条件后能力切换到就绪状态。
-
终止(Terminated):过程执行实现或被操作系统终止,开释所有调配的资源。
9.Spring Boot Actuator?
Spring Boot Actuator 为 Spring Boot 框架提供了弱小的性能,用于监控和治理 Spring Boot 应用程序。它提供了一系列的 REST API,能够让开发者通过 HTTP 申请来获取应用程序的运行时信息,如健康状况、内存应用状况、线程信息、日志等。同时,Actuator 还反对自定义的端点,能够依据我的项目需要增加自定义的监控和治理性能。通过 Actuator,开发者能够不便地监控和管理应用程序的运行状态,以及进行一些特定的操作,如动静批改日志级别、从新加载配置等。
Spring Boot Actuator 更多内容可拜访:https://juejin.cn/post/7052857798530433031#heading-7
10. 外键、主键和索引?
在数据库中,外键、主键和索引是三个不同的概念。
- 主键(Primary Key):主键是用来惟一标识一条记录的字段或字段组合。每张表只能有一个主键,主键的值不能反复且不能为空。主键的作用是保证数据的完整性和唯一性,放慢数据检索速度。
- 外键(Foreign Key):外键是用来建设表与表之间的关联关系的字段。它指向另一张表的主键,用来放弃数据完整性和一致性。外键能够确保数据之间的援用关系,并且在删除或更新操作时能够主动解决关联表中的数据。
- 索引(Index):索引是为了进步数据检索速度而创立的数据结构。它相似于书籍的目录,能够依据某个字段或字段组合疾速定位到具体的数据记录。索引能够放慢数据检索的速度,但会占用额定的存储空间,并且在插入、删除和更新操作时会有肯定的性能影响。
但在理论开发中,因为性能的起因,所以咱们很少用到真正的外键,也就是“物理外键”(应用 FOREIGN KEY 创立),而是在程序中应用逻辑外键来“建设”多张表的外键关系。
阿里巴巴《Java 开发手册》中也明确规定禁止应用数据库的外键,如下图所示:
11.TCP 和 UDP 区别?
TCP(传输控制协议)和 UDP(用户数据报协定)是两种罕用的网络传输协定。
TCP 是一种面向连贯的协定,它提供牢靠的数据传输。在 TCP 通信中,数据被分成多个小片段,每个片段都会被编号和校验,确保数据完整性。TCP 应用确认机制,确保数据的可靠性,如果发送方没有收到确认信息,会从新发送数据。TCP 还解决拥塞管制,依据网络条件动静调整数据传输的速率。TCP 实用于须要保障数据完整性和可靠性的利用,如文件传输、电子邮件等。
UDP 是一种面向无连贯的协定,它提供不牢靠的数据传输。在 UDP 通信中,数据被封装成数据包,间接发送给接管方,不须要建设连贯。UDP 不提供数据校验、确认机制和拥塞管制,因而传输速度较快,但容易产生数据失落。UDP 实用于实时传输要求较高的利用,如音频、视频流等。
所以,总结来说:TCP 是牢靠的、有序的、面向连贯的传输协定,而 UDP 是简略的、不牢靠的、无连贯的传输协定。抉择 TCP 还是 UDP 要依据具体的利用需要来确定。
12. 说一下哈西表?
哈希表(Hash Table),也称为散列表,是一种罕用的数据结构,用于实现键值对的存储和疾速检索。
哈希表的核心思想是通过哈希函数将键映射到一个固定大小的数组索引上,将键值对存储在该索引地位上。当须要查找或插入数据时,通过哈希函数计算出键对应的索引,而后在该地位上进行操作,从而实现疾速的数据拜访。
哈希表的长处是在均匀状况下具备常数工夫复杂度 O(1) 的查找、插入和删除操作。然而,在极其状况下,哈希抵触可能会导致性能降落,须要解决抵触的办法,如凋谢地址法(线性探测、二次探测等)或链表法(在抵触地位上应用链表存储多个键值对)。
哈希表广泛应用于各种编程场景中,如数据库索引、缓存零碎、编译器中的符号表等,它提供了高效的数据拜访和操作效率。
在 Java 中,哈希表的常见实现类有 Hashtable、HashMap 和 ConcurrentHashMap。
13. 防止哈希抵触办法?
解决哈希抵触的罕用办法有以下三种:链地址法、凋谢地址法和再哈希法。
- 链地址法(Separate Chaining):将哈希表中的每个桶都设置为一个链表,当产生哈希抵触时,将新的元素插入到链表的开端。这种办法的长处是简略易懂,实用于元素数量较少的状况。毛病是当链表过长时,查问效率会升高。
- 凋谢地址法(Open Addressing):当产生哈希抵触时,通过肯定的探测办法(如线性探测、二次探测、双重哈希等)在哈希表中寻找下一个可用的地位。这种办法的长处是不须要额定的存储空间,实用于元素数量较多的状况。毛病是容易产生汇集景象,即某些桶中的元素过多,而其余桶中的元素很少。
- 再哈希法(Rehashing):当产生哈希抵触时,应用另一个哈希函数计算出一个新的哈希值,而后将元素插入到对应的桶中。这种办法的长处是简略易懂,实用于元素数量较少的状况。毛病是须要额定的哈希函数,且当哈希函数不够随机时,容易产生汇集景象。
在 Java 中,HashMap 应用的是链地址法来解决哈希抵触的。
14. 说一下 JVM?
JVM(Java Virtual Machine,Java 虚拟机)是 Java 程序的运行环境,它负责将 Java 字节码翻译成机器代码并执行。也就是说 Java 代码之所以可能运行,次要是依附 JVM 来实现的。
JVM 整体的大略执行流程是这样的:
- 程序在执行之前先要把 Java 代码转换成字节码(class 文件),JVM 首先须要把字节码通过肯定的形式 类加载器(ClassLoader) 把文件加载到内存中 运行时数据区(Runtime Data Area);
- 但字节码文件是 JVM 的一套指令集标准,并不能间接交个底层操作系统去执行,因而须要特定的命令解析器,也就是 JVM 的执行引擎(Execution Engine)会 将字节码翻译成底层零碎指令再交由 CPU 去执行;
- 在执行的过程中,也须要调用其余语言的接口,如通过调用本地库接口(Native Interface) 来实现整个程序的运行。
JVM 具备以下特点:
- 平台无关性:JVM 使得 Java 程序能够在不同的操作系统和硬件平台上运行,而不须要从新编译和调整。
- 安全性:JVM 能够对 Java 程序进行平安治理,避免恶意代码的攻打和毁坏。
- 内存治理:JVM 能够主动治理内存,包含调配和回收内存空间,以防止内存透露和解体。
- 字节码执行:JVM 能够执行 Java 字节码文件,而不须要解释器或编译器。
JVM 的实现有多种规范和非标准的形式,包含 HotSpot JVM、GraalVM、Jython 和 JRuby 等。不同的 JVM 实现有不同的性能和性能个性,须要依据具体的利用场景进行抉择。
JVM 内存布局共有以下 5 局部:
- 程序计数器(Program Counter Register):用于记录以后线程执行的字节码指令地址,是线程公有的,线程切换不会影响程序计数器的值。
- Java 虚拟机栈(Java Virtual Machine Stacks):用于存储办法执行时的局部变量表、操作数栈、动静链接、办法进口等信息,也是线程公有的。每个办法在执行时都会创立一个栈帧,栈帧蕴含了办法的局部变量表、操作数栈等信息。
- 本地办法栈(Native Method Stack):与 Java 虚拟机栈相似,用于存储本地办法的信息。
- Java 堆(Java Heap):用于存储对象实例和数组,是 JVM 中最大的一块内存区域,它是所有线程共享的。堆通常被划分为年老代和老年代,以反对垃圾回收机制。
- 年老代(Young Generation):用于寄存新创建的对象。年老代又分为 Eden 区和两个 Survivor 区(通常是一个 From 区和一个 To 区),对象首先被调配在 Eden 区,通过垃圾回收后存活的对象会被移到 Survivor 区,通过屡次回收后依然存活的对象会降职到老年代。
- 老年代(Old Generation):用于寄存存活工夫较长的对象。老年代次要寄存长时间存活的对象或从年老代降职过去的对象。
- 办法区(Methed Area):用于存储已被虚拟机加载的类信息、常量、动态变量、即时编译器编译后的代码等数据。办法区也是所有线程共享的。
15. 我的项目中应用了哪些设计模式?
答复此问题,能够从一些罕用的设计模式动手,比方以下这些:
- 单例模式:因为我的项目是 Spring Boot 我的项目,所以默认注入的所有对象都是单例模式,或者说我的项目中的某一个类就是通过双重效验锁的形式实现了单例模式。
- 工厂模式:我的项目中应用了线程池来实现一个接口的多个数据组装,之后再对立返回后果的,而线程池是通过默认的线程工厂实现的,所以也应用到了工厂模式。
- 观察者模式:如果我的项目中应用了 Spring Event 或者 Google Guava EventBus,那么就能够说你我的项目中应用了观察者模式,因为 Event(事件)自身是基于观察者模式实现的。
- 公布订阅者模式:如果你的我的项目中应用了消息中间件,比方 Kafka、RabbitMQ、RocketMQ 等,那么你就能够说你的我的项目中应用了公布、订阅者模式,因为音讯队列自身就是公布订阅者模式。
- 策略模式:策略模式定义了一系列的算法,把它们一个个封装起来,并且使它们能够相互替换。策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵便、可保护、可扩大。比方用户登录蕴含了:账号密码登录、手机验证码登录和第三方登录等,咱们把不同的登录形式封装成不同的登录策略,这就是策略模式。
-
模板办法模式:它在超类中定义了一个算法的框架,容许子类在不批改构造的状况下重写算法的特定步骤。比方后盾的数据上传性能,既反对 DOC 格局,又反对 CSV 格局,那么咱们就在超类中定义执行的步骤,而后再实现各自类中重写读取办法,因为 DOC 和 CSV 的读写办法是不同的,这就是典型的模板办法模式。
16. 什么是线程平安?
线程平安是指在多线程环境下,程序的行为不会被其余线程的烦扰所影响,保障了多个线程同时访问共享资源时的正确性和可靠性。
在 Java 中,为了保障线程平安,能够应用 synchronized 关键字或者 Lock 接口来实现同步。synchronized 关键字能够保障同一时刻只有一个线程可能访问共享资源,而 Lock 接口则提供了更加灵便的管制形式。
小结
TP-LINK 总体面试难度个别,可能是因为面试工夫的起因,所以很多常识的底层实现和细节问的比拟少,这对于大部分应聘者来说是坏事。所以机会比能力更重要,而投递简历的数量决定了机会的多少,所以放松投递简历吧。
本文已收录到我的面试小站 www.javacn.site,其中蕴含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、音讯队列等模块。