先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注运维)
正文
public static void so(Object obj) {
String str = "";
if(obj instanceof int[]) {
int[] arr = (int[])obj;
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i : arr) {
sb.append(i+",");
}
str = sb.substring(0,sb.lastIndexOf(","))+"]" ;
}else if(obj instanceof long[]) {
long[] arr = (long[])obj;
StringBuilder sb = new StringBuilder();
sb.append("[");
for (long i : arr) {
sb.append(i+",");
}
str = sb.substring(0,sb.lastIndexOf(","))+"]" ;
}else if(obj instanceof char[]) {
char[] arr = (char[])obj;
StringBuilder sb = new StringBuilder();
sb.append("[");
for (char i : arr) {
sb.append(i+",");
}
str = sb.substring(0,sb.lastIndexOf(","))+"]" ;
}else if(obj instanceof short[]) {
short[] arr = (short[])obj;
StringBuilder sb = new StringBuilder();
sb.append("[");
for (short i : arr) {
sb.append(i+",");
}
str = sb.substring(0,sb.lastIndexOf(","))+"]" ;
}else if(obj instanceof double[]) {
double[] arr = (double[])obj;
StringBuilder sb = new StringBuilder();
sb.append("[");
for (double i : arr) {
sb.append(i+",");
}
str = sb.substring(0,sb.lastIndexOf(","))+"]" ;
}else if(obj instanceof float[]) {
float[] arr = (float[])obj;
StringBuilder sb = new StringBuilder();
sb.append("[");
for (float i : arr) {
sb.append(i+",");
}
str = sb.substring(0,sb.lastIndexOf(","))+"]" ;
}else if(obj instanceof Object[]) {
Object[] arr = (Object[])obj;
StringBuilder sb = new StringBuilder();
sb.append("[");
for (Object i : arr) {
sb.append(i.toString()+",");
}
str = sb.substring(0,sb.lastIndexOf(","))+"]" ;
}else {
str=obj.toString();
}
System.out.println(str);;
}
}
最佳情况:T(n) = O(n) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)
#### 2、选择排序(Selection Sort)
表现最稳定的排序算法之一,因为无论什么数据进去都是O(n2)的时间复杂度,所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。理论上讲,选择排序可能也是平时排序一般人想到的最多的排序方法了吧。
选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
2.1 算法描述
n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下:
* 初始状态:无序区为R[1..n],有序区为空;
* 第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1..i-1]和R(i..n)。该趟排序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R[i+1..n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;
* n-1趟结束,数组有序化了。
2.2 动图演示

2.3 代码实现
package cn.fuqiang.arithmetic;
import java.util.Comparator;
/**
-
选择排序 的两种实现方式
-
(在这里要注意,因为最后一个位置的数绝对是最后循环后最大的值,
-
所以外层循环的循环次数 最好是arr.length-1).
-
@author 王福强
-
@Title: SelectionSort.java
-
@Package cn.fuqiang.arithmetic
-
@Description
-
@date 2018年6月8日 下午5:30:59
*/
public class SelectionSort {
public static void main(String[] args) {
int[] arr = {4,1,5,3,8,10,28,2};
sort(arr);
so(arr);Integer[] arr2 = {4,1,5,3,8,10,28,2}; sort(arr2,(a,b)-> b.compareTo(a)); so(arr2);
}
/**
- 选择排序 第一种实现方式 (赋值) 升序 (特点 :从小到大)
- 原理: 每次把最小的都放在前面,
- 外层循环控制每次遍历的次数,内层循环替换每次找出来的最小值,放在 arr[i]的位置
- 这样当内层比较和替换的时候,就保证每次最小的都在最前面
- 例如:3 2 6 1
- 第一次外层循环为 i 为 0 第一个就是最小的值放最小的值
- 内层循换会把每次找出的最小值放在arr[0] 的位置
- 第二次外层循环为 i 为 1
- 内层循环会把每次找出最小的值放在 arr[1] 的位置
- 外循环 第一次 i=0
- 内部循环
- 第一次 2 3 6 1
- 第二次 2 3 6 1
- 第三次 1 3 6 2
- 外循环 第二次 i=1
- 内部循环
- 第一次 3 6 1
- 第二次 1 6 3
- 外循环 第三次 i=2
- 内部循环
- 第一次 3 6
- @author 王福强
- @Description
- @date 2018年6月8日 下午6:36:42
- @param arr int类型数组
*/
public static void sort(int[] arr) {
for(int i = 0;i<arr.length-1;i++) {
int temp;
for(int j = i+1 ; j <arr.length ; j++) {
if(arr[i]>arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
/**
- 选择排序 第二种实现(记录下标) 升序 (特点 :从小到大)
- 每次循环记录最小的下标 min 最后跟 arr[i] 位置的下标交换位置
- 这样当外层循环每次循环一次 会先记下 arr[i] 的下标,
- 然后让内层循环从 i+1 开始比较去比较 arr[min] 与 arr[j]
- 如果 min下表对应的值 比 j下标对应的值大, 则记录 j的下标 min = j
- 然后拿新的 min下标去跟后面比较,依此类推。
- 当内层循环循环结束后记录的下标是剩余数中最小的呢个值的下标
- 然后用一个零时变量将他们的值交换过来,就算本身是最小的,也是替换自己
- 例如 1 3 6 2
- 第一次外层循环结束后
- 1 3 6 2
- 第二次外循开始时,会记录i的下标
- 然后开始内层循环,会记录2的下标
- 内层循环结束后,会把 3 与 2的位置调换
- 2 6 3
- 。。。。。
- 。。。。
- 3 6
- @author 王福强
- @Description
- @date 2018年6月9日 下午2:13:42
- @param arr
- @param comparator
*/
public static void sort(T[] arr,Comparator comparator) {
for(int i = 0;i<arr.length-1;i++) {
int min=i;
T temp=null;
for(int j = i+1 ; j <arr.length ; j++) {
if(comparator.compare(arr[min], arr[j])<0) {
min = j;
}
}
temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
/**
-
传入任意数组或对象 输出到控制台
-
@author 王福强
-
@Description 前提是传入的对象必须重写 toString()方法
-
@date 2018年6月8日 下午4:26:06
-
@param obj
*/
public static void so(Object obj) {
String str = “”;
if(obj instanceof int[]) {
int[] arr = (int[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (int i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;}else if(obj instanceof long[]) {
long[] arr = (long[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (long i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof char[]) {
char[] arr = (char[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (char i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof short[]) {
short[] arr = (short[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (short i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof double[]) {
double[] arr = (double[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (double i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof float[]) {
float[] arr = (float[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (float i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof Object[]) {
Object[] arr = (Object[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (Object i : arr) {
sb.append(i.toString()+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else {
str=obj.toString();
}
System.out.println(str);;
}
}
2.4 算法分析
最佳情况:T(n) = O(n2) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)
#### 3、插入排序(Insertion Sort)
插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
3.1 算法描述
一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:
* 从第一个元素开始,该元素可以认为已经被排序;
* 取出下一个元素,在已经排序的元素序列中从后向前扫描;
* 如果该元素(已排序)大于新元素,将该元素移到下一位置;
* 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
* 将新元素插入到该位置后;
* 重复步骤2~5。
3.2 动图演示

3.2 代码实现
package cn.fuqiang.arithmetic;
import java.util.Comparator;
/**
-
插入排序
-
@author 王福强
-
@Title: InsertionSort.java
-
@Package cn.fuqiang.arithmetic
-
@Description
-
@date 2018年6月11日 下午2:19:55
*/
public class InsertionSort {
public static void main(String[] args) {
int[] arr = {4,1,5,3,8,10,28,2};
sort(arr);
so(arr);Integer[] arr2 = {4,1,5,3,8,10,28,2}; sort(arr2,(a,b)-> b.compareTo(a)); so(arr2);
}
/**- 插入排序 升序(特点:拿当前下标值与前面的值比较,将小的值排在对应的位置,把大的往后移)
- 循环从 i=1 开始 用temp记录当前位置的值arr[i],
- 然后设置内部循环控制下标,通过循环将下标每次减一。
- 然后判断temp与arr[index]的大小, 如果temp小于arr[index]则将arr[index-1]值移动到下一个位置,
- 然后将下标往前挪一位 也就是 index-1 (因为第一次比较时记录了 temp = arr[i] 所以不用担心会将值覆盖)
- 如果不进入内循环则说明,下标已经移动到最前面了没有比该值更小的了,
- 这时候就把记录的 temp 赋值给 index+1 的位置上(因为index已经减到前一个了)
- 比较第一个位置 和第二个位置的
- 例如 3 1 6 2
- 外循环第一次 i=1
- 外层循环直接从 下标为一的开始
- 比较1 与3的大小,然后把3的位置移动到后面一位,
- 应为内层循环index–后小于0了,所以不在循环,
- 然后因为把3移动到后面一位的时候前面空了一个位置,所以就把1插入
- 1 3 6 2
- 。。。。
- 外循环第三次 i=3
- 比较 2 与 6 然后把6往后移
- 比较 2与3把三往后移
- 然后比较2与1 把 2 插入到空缺位置
- @author 王福强
- @Description
- @date 2018年6月11日 下午4:22:41
- @param arr
*/
public static void sort(int[] arr) {
for(int i = 1 ; i < arr.length ; i ++) {
int index = i-1;
int temp = arr[i];
while(index>=0 && arr[index]>temp) {
arr[index+1] = arr[index–];
}
arr[index+1] = temp;
}
}
/**
- 对任意对象排序
- @author 王福强
- @Description
- @date 2018年6月13日 上午10:52:31
- @param arr
- @param comparator
*/
public static void sort(T[] arr,Comparator comparator) {
for(int i = 1;i<arr.length;i++) {
T temp=arr[i];
int index;
for(index = i-1;index>=0 && comparator.compare(arr[index], temp)<0;index–) {
arr[index+1]=arr[index];
}
arr[index+1] =temp;
}
}
/**
-
传入任意数组或对象 输出到控制台
-
@author 王福强
-
@Description 前提是传入的对象必须重写 toString()方法
-
@date 2018年6月8日 下午4:26:06
-
@param obj
*/
public static void so(Object obj) {
String str = obj.toString();
if(obj instanceof int[]) {
int[] arr = (int[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (int i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;}else if(obj instanceof long[]) {
long[] arr = (long[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (long i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof char[]) {
char[] arr = (char[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (char i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof short[]) {
short[] arr = (short[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (short i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof double[]) {
double[] arr = (double[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (double i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof float[]) {
float[] arr = (float[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (float i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof Object[]) {
Object[] arr = (Object[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (Object i : arr) {
sb.append(i.toString()+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else {
str=obj.toString();
}
System.out.println(str);;
}
}
3.4 算法分析
最佳情况:T(n) = O(n) 最坏情况:T(n) = O(n2) 平均情况:T(n) = O(n2)
#### 4、希尔排序(Shell Sort)
1959年Shell发明,第一个突破O(n^2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。
希尔排序的核心在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态的定义间隔序列。动态定义间隔序列的算法是《算法(第4版》的合著者Robert Sedgewick提出的。
4.1 算法描述
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:
* 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
* 按增量序列个数k,对序列进行k 趟排序;
* 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
4.2 过程演示


4.3 代码实现
package cn.fuqiang.arithmetic;
import java.util.Comparator;
/**
-
希尔排序
-
(建议:研究希尔排序前先理解插入排序)
-
@author 王福强
-
@Title: ShellSort.java
-
@Package cn.fuqiang.arithmetic
-
@Description
-
@date 2018年6月11日 下午7:23:24
*/
public class ShellSort {
public static void main(String[] args) {
int[] arr = {4,1,5,3,8,10,28,2};
sort(arr);
so(arr);
Integer[] arr2 = {4,1,5,3,8,10,28,2};
sort(arr2,(a,b)-> a.compareTo(b));
so(arr2);}
/**- 希尔排序 升序(特点:缩小增量排序 ,是插入排序的改进版)
- increment是用来记录增量的
*讲解: - while(increment > 1)
- 最外层的 while循环是用来控制增量的。增量要从大到小
- increment =increment/3+1;
- 当每次循环后都吧增量除以一个数(改数不能是2和1 否则会死循环)加一
- 保证最后除尽后不能小于一,应为最后增量缩小为一后需要两两之间进行比较(此处也就是缩小增量)
- for (int i = increment; i < arr.length; i++) {
- 中间for循环,控制每次要取出的比较的元素,从增量开始,每次加一
- int temp = arr[i];
- 用一个零是变量接受要比较的值
- arr[j+increment] = temp;
- 因为在内层循环中已将前面的值移动到后面了,在最后一次 循环结束后 j -= increment 已经少了一个增量
- 所以j+increment 正好是移动后最后空出来的一个 所以把temp替换给该值,完成交换
- 就算没有进入内层循环,呢j=i-incement后再+incement就还是 i本身temp也就是arr[i]本身
- for (j = i-increment; j >= 0 && arr[j]> temp ; j-=increment) {
- 最内层的for循环是用来控制temp 与每个j-increment个值比较,从 j=i-increment开始 也就是中层循中 i减去一个增量后的下标(与插入排序相同,只不过是每次跟前increment个值比较)
- j >= 0 && arr[j]> temp
- 该判断是防止j减到负下标并且每次替换的实话 只有temp小于arr[j]才可以进入
- arr[j+increment] = arr[j];
- 如果arr[j]> temp 呢么与将 arr[j]的值移动道后面
- 例如
- 4,1,5,3,8,10,28,2 长度为 8
- while循环第一次
-
increment = 3
- 中层for循环 i从 3开始
-
temp = arr[3]
-
内层for循环从j=i-increment 也就是从前increment个值开始
-
就会拿出arr[3-3]>temp 比较
-
如果temp小则 把 arr[3-3] 的值与 的值赋给arr[0+3] 也就是 arr[j+increment] = arr[j]
-
因为arr[3]已经记录,所以当 j-=increment时 j=-3此时已经不满足 j >= 0 所以内层循环结束
-
内层循环结束后 arr的值就从4,1,5,3,8,10,28,2 变为了 4,1,5,4,8,10,28,2
-
因为在内层循环中只是把 0下标的值赋给了3下标 所以说 0位置的值还是4
-
此时中层循环中的 arr[j+increment] = temp; 就是把原来记录的 arr[3]----3 赋给0下标,
-
因为j已经被减了increment 变成了-3所以此时加上increment正好等于0下标
-
所以arr就变成了 3,1,5,4,8,10,28,2
- 中层for循环 i变为了4
-
temp = arr[4]
-
内层for循环从j=i-increment 也就是从前increment个值开始
-
就会拿出arr[4-3]>temp 比较
-
因为arr[1]小于temp所以 而且j也已经=-1所以循环结束
- 。。。。。。。。。 以此类推
- @author 王福强
- @Description
- @date 2018年6月14日 下午5:33:04
- @param arr
*/
public static void sort(int[] arr) {
int increment = arr.length;
while(increment > 1) { //动态定义间隔序列
increment =increment/3+1;
for (int i = increment; i < arr.length; i++) {
int temp = arr[i];
int j ;
for (j = i-increment; j >= 0 && arr[j]> temp ; j-=increment) {
arr[j+increment] = arr[j];
}
arr[j+increment] = temp;
}
}
}
/**
-
任意对象排序,将上面排序中 内部的循环替换为了while循环
-
@author 王福强
-
@Description
-
@date 2018年6月15日 下午3:45:06
-
@param arr
-
@param comparator
/
public static void sort(T[] arr,Comparator comparator){
int increment = arr.length;
while(increment > 1) { //动态定义间隔序列
increment =increment/3+1;
for (int i = increment; i < arr.length; i++) {
T temp = arr[i];
int j = i-increment;
while ( j >= 0 && comparator.compare(arr[j], temp)>0 ) {
arr[j+increment] = arr[j];
j-=increment;
}
arr[j+increment] = temp;
}
}
}
/* -
传入任意数组或对象 输出到控制台
-
@author 王福强
-
@Description 前提是传入的对象必须重写 toString()方法
-
@date 2018年6月8日 下午4:26:06
-
@param obj
*/
public static void so(Object obj) {
String str = obj.toString();
if(obj instanceof int[]) {
int[] arr = (int[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (int i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;}else if(obj instanceof long[]) {
long[] arr = (long[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (long i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof char[]) {
char[] arr = (char[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (char i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof short[]) {
short[] arr = (short[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (short i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof double[]) {
double[] arr = (double[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (double i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof float[]) {
float[] arr = (float[])obj;
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注运维)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
Builder sb = new StringBuilder();
sb.append(“[”);
for (short i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof double[]) {
double[] arr = (double[])obj;
StringBuilder sb = new StringBuilder();
sb.append(“[”);
for (double i : arr) {
sb.append(i+“,”);
}
str = sb.substring(0,sb.lastIndexOf(“,”))+“]” ;
}else if(obj instanceof float[]) {
float[] arr = (float[])obj;
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注运维)
[外链图片转存中…(img-o662bdMJ-1713228412500)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!