# 公司概况

# 合合信息

笔试题还未找到。。

# 用友软件

1.@Autowired 和 @Resource 有什么区别,@Autowired 怎么根据 name 注入

2. 从配置文件注入属性的注解,有没有遇到过 @Value 注入的时候注入不进来的情况

3. 经典面试题:输入 URL 到页面显示的整个流程

4. 有没有遇到过 @RequestMapping 写的接口,断点在第一行,debug 时候第一行都没进去的情况,怎么解决?

5. 为什么 TCP 要三次握手,两次不行

6. 说一下 HTTP 的理解,协议属性、安不安全、常用 method、报文头报文体的字段

7.get 和 post 的区别,URL 长度限制,post 和 put 有什么区别

8. 数据库三范式

9. 爱好可以存一个字符串,爱好直接拼接起来和爱好单独存一个表的区别

10. 执行计划怎么分析,怎么优化 SQL

# 已知二叉树后序遍历序列为 dabec,中序遍历序列为 debac, 那么它的前序遍历序列是?

cedba

# 哪些排序算法是不稳定算法

在排序算法中,稳定排序算法是指,如果待排序的序列中存在值相等的元素,经过排序后这些元素的相对位置不会改变。

下面列举几个常见的不稳定排序算法:

  1. 快速排序(Quick Sort):快速排序使用分治策略,选取一个基准值将数组分为两部分,然后递归地对子数组进行排序。在分割数组时,可能会导致元素的相对位置发生改变,从而破坏了稳定性。
  2. 堆排序(Heap Sort):堆排序使用堆数据结构进行排序,它不保证相等元素的顺序不变。在交换堆顶元素和尾部元素的过程中,有可能会改变相同元素的相对位置。
  3. 希尔排序(Shell Sort):希尔排序也被认为是一种不稳定的排序算法,因为在不同的增量序列下,相等元素的顺序可能会发生改变。

需要注意的是,虽然上述排序算法都是不稳定的,但是它们都具有高效的时间复杂度。在实践中,选择合适的排序算法需要根据具体问题的需求来决定,不能仅仅考虑稳定性。

# 关于常用限流算法

常用的限流算法有以下几种:

  1. 固定窗口算法(Fixed Window Algorithm):固定窗口算法将单位时间划分为固定大小的窗口,比如每秒钟一个窗口。在每个窗口内,设置一个固定的阈值,如果请求数量超过阈值,则进行限流。这种算法简单直观,但可能会导致突发流量的问题。
  2. 滑动窗口算法(Sliding Window Algorithm):滑动窗口算法是对固定窗口算法的改进。它将时间划分为多个窗口,并通过滑动窗口的方式来统计请求数量。通过动态调整窗口的大小,可以更好地应对突发流量和平滑流量。
  3. 令牌桶算法(Token Bucket Algorithm):令牌桶算法通过引入令牌桶的概念来进行限流。令牌以固定的速率放入桶中,每当请求到达时,先尝试从桶中获取令牌,如果没有令牌则被限流。该算法能够应对突发流量并且具有较好的容错性。
  4. 漏桶算法(Leaky Bucket Algorithm):漏桶算法模拟了一个水桶,请求被看作是水滴,以固定的速率从桶中漏出。如果请求到达时,桶已满,则进行限流。该算法能够平滑流量并且具有较好的稳定性。

在实际应用中,选择适合的限流算法需要根据具体的业务需求和系统特点来进行评估和比较。同时,也可以根据实际情况结合多种算法进行组合使用,以达到更好的限流效果。

# 大华股份

# 中兴软件

# 对于 n 个互不相同的符号进行哈夫曼编码,若生成的哈夫曼树共有 35 个结点,则 n 的值为?

哈夫曼树的特点性质:(节点为的度数为 0 表示 n0, 以此类推)
①哈夫曼树中只存在度为 2 和度为 0 的节点,及 n1=0。
②哈夫曼树中,度为 0 和度为 2 的节点关系:n2=n0-1

由以上两个性质,本题就很好解出答案:
n0+n2=35 =>
n0+n0-1=35 =>
n0=(35+1)/2=18

# SQL 中 COUNT 和 SUM 的区别

count 统计函数,

sum 关注的是数值列的总和。

# 浩鲸科技

# 与事务控制相关的语句

事务控制通常涉及以下语句:

  1. BEGIN TRANSACTION:此语句用于开启一个新的事务。在事务开始之后,所有的数据库操作都包含在该事务中,直到显式地停止该事务。
  2. COMMIT:此语句用于提交事务。在提交事务之后,所有的数据库操作将被永久地保存到数据库中。
  3. ROLLBACK:此语句用于回滚事务。在回滚事务之后,所有的数据库操作将被撤销,数据库状态将回到事务开始之前的状态。
  4. SAVEPOINT:此语句用于在事务中创建一个保存点。如果在事务中需要回滚操作,可以使用 SAVEPOINT 来只回滚一部分操作。
  5. RELEASE SAVEPOINT:此语句用于删除一个保存点。当不再需要一个保存点时,可以使用此语句将其删除。
  6. ROLLBACK TO SAVEPOINT:此语句用于回滚到指定的保存点。如果在事务中某个操作需要回滚,但不想回滚整个事务,可以使用此语句回滚到指定的保存点。

这些语句用于控制数据库事务的流程,确保数据的完整性和一致性。

# 索引为什么不能直接从 select 语句中引用

在 SELECT 语句中引用索引可能会导致查询优化器做出不正确的决策,因为它可能无法正确评估使用索引是否会提高查询性能。

# 隐式提交事务的操作命令有?

这里详细列举这些命令:

  1. create:用于创建新的数据库对象,如表、视图、存储过程等。
  2. drop:用于删除数据库中的对象,如表、视图、存储过程等。
  3. alter:用于修改表的结构,如添加、修改或删除列。
  4. grant:用于授予用户对数据库的权限,如读取、写入或执行存储过程等。
  5. revoke:用于撤销用户对数据库的权限。
  6. exit:用于退出 sqlplus。

这些命令在执行时会自动提交以前的所有更新操作,无需手动提交。需要注意的是,这些命令只适用于某些特定的数据库管理系统,不同的系统可能会有不同的命令来实现隐式提交操作。

# 关于 ArrayList,初始化指定容量为 10,在添加第 11 个元素时,会发生什么?

当你创建一个具有特定容量的 ArrayList (例如,通过使用 new ArrayList<>(10) 来初始化一个具有 10 个元素的 ArrayList ),然后尝试添加第 11 个元素时,会发生以下情况:

  1. 如果该 ArrayList 还没有被使用,即其当前容量足以容纳新元素,那么新元素就会被添加到 ArrayList 中。
  2. 如果 ArrayList 已经被完全使用(即所有当前可用的空间都已经被使用),那么 ArrayList 的容量将会自动增加。默认情况下,每次 ArrayList 达到其容量极限时,它的容量会翻倍。因此,当你添加第 11 个元素时, ArrayList 的容量将会自动增加到至少 20。

这种自动扩容的过程是 ArrayList 的内部处理,对于大多数应用来说是透明的。你只需要关注如何添加元素就可以了, ArrayList 会自动处理其内部数据的扩容。

需要注意的是,虽然 ArrayList 会自动扩容以容纳更多的元素,但这并不意味着你可以无限制地向 ArrayList 中添加元素。如果你添加的元素超过了 ArrayList 的最大容量(即数组的最大大小,由 Integer.MAX_VALUE 决定),那么将会抛出 OutOfMemoryError

# 冯诺伊曼体系结构的理解

冯・诺伊曼体系结构,也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。这种体系结构是遵循图灵机的设计和冯・诺伊曼提出的计算机系统设计的五个基本部分构建的。

根据这种结构,计算机的程序和数据都存储在同一个存储器中,即内存。指令和数据可以同时被取出,放入寄存器进行相应的计算,然后再送回内存。因此,这种结构的特点是 “程序存储,共享数据”。

具体来说,冯・诺伊曼体系结构有以下特点:

  1. 单处理机结构:机器以运算器为中心。
  2. 采用程序存储思想:程序指令存储地址和数据存储地址指向同一个存储器的不同物理位置,因此程序指令和数据的宽度相同。
  3. 指令和数据一样可以参与运算。
  4. 数据以二进制表示。
  5. 将软件和硬件完全分离:这种分离使得程序设计变得更加灵活,对机器硬件的设计也更加容易。
  6. 指令由操作码和操作数组成:操作码指定了指令要执行的操作类型,操作数则给出了操作的对象。
  7. 指令顺序执行:这是冯・诺伊曼体系结构的一个主要特点,即指令按照顺序一条一条地执行。

然而,这种结构也存在一些局限性。例如,由于 CPU 与共享存储器间的信息交换速度成为影响系统性能的主要因素,因此信息交换速度的提高又受制于存储元件的速度、存储器的性能和结构等诸多条件。

总的来说,冯・诺伊曼体系结构是一种经典的计算机体系结构,它奠定了现代计算机的基础,几乎所有的现代计算机都遵循这种结构。


# 联想

22 届联想笔试题

9.2 日

# Java IO 体系中,read 方法从输入流中顺序读取源中的单个字节数据,如果未达到源的末尾,该方法返回什么?

答:返回 - 1,表示到达源的末尾,这是一个参数,表示没有任何更多的数据可读了。

# Java IO 体系中,通常情况下以下哪个类可用来读取文件且产生的系统调用可能是最少的?

优先选择 BufferedInputstream

可以使用 FileInputStream 并不代表这是最佳的选择,在某种情况下,比如处理大型文件或者需要高效处理大量数据的情况下,可能需要考虑使用其它类。比如 BufferedInputStream 或者 FileChannel。这些类提供了更高级的缓冲和 I/O 操作,可以提高读取和写入文件的效率。

# Java IO 操作中,什么方法可以直接将缓冲中的数据立即发送到网络中?

在 IO 中,可以使用 flush () 方法将缓冲区的数据立即发送的网络中,flush () 方法会强制将所有有缓冲的数据输出字节发送到目标处。原因是在内存中的缓存极有可能被丢失,所以在写入重要数据后,通常需要使用 flush () 方法确保数据被发送到目标处。

# 以下代码执行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package TestJava;

/*
* @Author: jun
* @Date:2023/9/3 18:58
* @概述:
*/
public class LXXZtest01 {

public static void main(String[] args) {
Integer num1 = 200 ;
Integer num2 = 200 ;
if (num1 != num2) {
System.out.println(1);
}else {
System.out.println(2);
}
if (!num1.equals(num2)) {
System.out.println(3);
}else{
System.out.println(4);
}
}
}

首先对于这里的情况,尽管 num1 和 num2 都是 200,但它们是两个不同的对象。因为在 Java 中,对基本数据类型的包装类(如 Integer,Double 等)使用 “==” 运算符比较的是对象的引用是否相等,而非值是否相等。所以这里 num1 != num2 为真,程序会输出 1。

其次,在第二个 if 语句中,使用 Object 类的 equals 方法来比较两个 Integer 对象,因为 Integer 类是继承自 Object 类,所以它重写了 Object 类的 equals 方法。在 Integer 类中,equals 方法被重写为比较两个整数的值是否相等。因此,num1.equals (num2) 为真,程序会输出 4。

# Java 中的转义字符分类

1、 双引号("") : 转义字符" 表示字符串中的双引号。一般用作字符串的定义

2、 单引号 (’ '): 转义字符 ’ 表示字符字面值。例如:char myChar = ‘’

3、 反斜杠 ( \ ):用来表示特殊的字符,\n 表示换行符,\t 表示制表符

4、 双反斜杠 \ \ : 表示转义符本身。

# 以下初始化的方法错误的是

A

Map<Integer, Byte> hashMap = new HashMap<Integer, Byte>();

B

Set setStr = new Set();

C

List arrayList = new ArrayList();

D

List linkedList = new LinkedList();

答案是:B

set 是 Set 集合的根接口,不能被实例化,只能实例它的实现类 HashSet,LinkedHashSet,TreeSet.

# Java new 对象实例通常存在以下哪个内存区域?

使用 new 关键字创建新的对象实例时,这个对象一般会在 Java 堆内存区域中,堆是 Java 内存管理的主要区域,它用于动态分配内存,用来存储实例对象。

堆(Heap):用来动态分配内存的主要区域,当使用 new 关键字来创建一个对象时,新创建的对象就会被放在堆内存中,对是一个非常大的内存区域,它的大小可以通过 -Xmx 和 -Xms JVM 参数来控制。

# Java 中,关于 this () 和 super () 的说法

this () 用于调用同一个类的其它构造函数

super () 用于调用父类的构造函数。

# 在 Java 中,我们所讲的本地接口书写程序或者本地方法接口指的是

在 Java 中,本地方法接口(Native Method Interface)通常指的是 Java 程序与本地 C 或 C++ 代码之间的接口。本地方法接口允许 Java 程序调用在本地代码中定义的函数和方法。

本地方法接口是通过 Java Native Interface(JNI)来实现的。JNI 是 Java 平台的一部分,它提供了一组 API,用于在 Java 应用程序中调用本地代码。通过 JNI,Java 程序可以访问操作系统 API、硬件和其他底层资源。

在本地方法接口中,Java 程序使用 Java 数据类型和 Java 方法,而本地代码则使用本地数据类型和本地方法。为了使 Java 程序能够调用本地代码,需要编写一个本地方法声明(通常是一个头文件),该声明描述了本地方法的名称、参数和返回类型。然后,可以使用 JNI API 将 Java 程序与本地代码连接起来。

使用本地方法接口可以实现高性能的 Java 应用程序,例如在视频处理、图形渲染和游戏开发等领域中。但是,编写和调试本地代码需要更多的工作量和技术能力。

# 以下代码输出结果是?

# 类加载问题

问题:

类定义源码如下: package com.lenovo.school.recruitment.project

public class ClassFinder {

public static void main(String[] args) {

System.out.println(“class finder”); }

}

假设工程目录为 D:\workspace\dome1 ,最有可能正确运行并输出 "class finder" 的是 java -cp D:\workspace\dome1\out com.lenovo.school.recruitment.project.ClassFinder

java -cp 和 -classpath 一样,是指定类运行所依赖其他类的路径,通常是类库,jar 包之类,需要全路径到 jar 包,window 上分号 “;”

分隔,linux 上是分号 “:” 分隔。不支持通配符,需要列出所有 jar 包,用一点 “.” 代表当前路径。 格式: java -cp .;myClass.jar packname.mainclassname 表达式支持通配符,例如: java -cp .;c:\classes01\myClass.jar;c:\classes02*.jar packname.mainclassname

# 标识符的声明

以字母、下划线、美元符号($) 开头

后续字符是字母、数字、下划线或者美元符号

标识符的长度一般为 32 位或者是 64 位。取决于开发语言

标识符不能是关键字

# Java 线程池的关键要素

1、核心线程数

2、 最大线程数

3、 队列

4、 工作线程

5、 拒绝策略

# 关于 @SpringBootApplication 注解

它包含了以下几个注解:

@SpringBootConfiguration

@EnableAutoConfiguration

@ComponentScan

要注意的是 @Configuration 是 Spring 的注解

# 关于 wait () 和 sleep () 方法

wait () 方法来至于 Object, 而 sleep () 方法来自与 Thread

两个方法都会暂停当前的线程

关于同步锁:sleep () 不会释放同步锁,而 wait () 方法会释放同步锁。

# Java 静态变量和成员变量的区别

1、声明方式不同:静态变量通过关键字 static 声明,而成员变量是在类的主体中声明的

2、生命周期不同:静态变量的生命周期是一个程序的整个运行周期,而成员变量的生命周期是取决于创建它的对象,对象开始到对象被销毁结束。这是它的生命周期。

3、存储位置不同:成员变量存放于堆内存中,静态变量存放在方法区中。

4、访问方式不同:静态变量可以通过类名来直接访问,成员变量的访问方式就是只能通过创建它的对象来访问。

5、所属关系不同:静态变量是属于类的,而成员变量是属于对象

6、初始化顺序不同:静态变量在程序开始运行的时候就进行初始化,而成员变量在对象创建的时候进行初始化、


# 奇安信运维

2020 年运维卷 1 20/48 答对,前 18%

# 对于一个文件的访问,由什么共同限制?

用户的文件权限和文件的属性

用户访问权限决定了哪些用户可以访问该文件,文件属性则规定了文件的各种信息,包括文件是否可读、可写或可执行等。

其他因素如优先级和口令等虽然也可能对文件访问产生影响,但并非主要限制因素。

# 一个有向无环图是否存在拓扑排序?

存在

通常可以利用拓扑排序的方法检测图中是否存在环。

过程:从起始点开始按拓扑排序依次删除结点,直到拓扑排序结束,如果依然有节点未被删除,那么是因为存在环,使得无法找到环的拓扑排序的入口。

# epoll ET 模式必须配合 non-blocking IO 使用吗?

是的,epoll 的 ET 模式必须配合非阻塞 IO 使用。

ET 模式是 epoll 工作的一种模式,它具有高速并且高效的特点。在这种模式下,当描述符从未就绪变为就绪时,内核通过 epoll 通知应用程序。然而,当一个文件描述符被设置为非阻塞时,如果读 / 写操作不能立即完成,操作将不会阻塞,而是立即返回。这样,应用程序可以立即进行其他操作,而不需要等待读 / 写操作完成。

如果文件描述符没有被设置为非阻塞,那么在读 / 写操作不能立即完成时,操作将会阻塞,直到数据可用或可写为止。这样,应用程序将需要等待读 / 写操作完成,而这可能会导致应用程序的效率降低。

因此,ET 模式必须配合非阻塞 IO 使用,以确保应用程序可以高效地处理文件描述符的就绪状态。

注:epoll 作为 Linux 内核处理文件描述符的 poll 改进版,是一种针对大量并发连接进行高效处理的 IO 管理方式。

# 在一个空目录下执行 umask 333; touch hello; 命令后,hello 文件的权限为?

-wx-wx-wx-

umask 是 linux 中的一个命令,用于设置文件创建的权限掩码。umask 的值是一个三位数,代表了用户、用户组和其它用户的权限。执行 umask 333 时,用户,用户组,和其它用户的写权限被禁用了。文件的默认值为 666,执行 umask 后,666-333=333(即 - wx-wx-wx-)

# 在 DNS 系统测试时,假设 named 进程号是 53,如何通知进程重读配置文件?

命令行的方式是:

1
kill -HUP 53

# mysql 中的视图的作用

在 MySQL 中,视图(View)是一种虚拟的表,它是由一个或多个查询语句生成的结果集。视图并不实际存储数据,而是基于存储在数据库中的源表(或其他视图)的数据进行计算和呈现。视图的作用主要包括以下几个方面:

  1. 简化复杂的查询:视图可以将复杂的查询逻辑封装起来,使用户可以像访问普通表一样使用视图。这样,用户无需关心底层的查询逻辑,简化了查询操作。
  2. 数据安全性:视图可以用于限制用户对数据的访问权限。通过创建适当的视图,用户只能看到他们被允许看到的数据,从而确保数据的安全性。
  3. 数据抽象:视图可以隐藏底层表的结构变化,使得用户无需关注表的结构变化对查询的影响。当底层表的结构发生变化时,只需相应地修改视图定义即可。
  4. 数据的汇总和转换:视图可以对多个表的数据进行汇总和转换,生成一个新的、虚拟的表结构,方便用户进行查询和分析。
  5. 方便的数据访问接口:视图可以作为一个常用的数据访问接口,为不同的用户提供个性化的数据视图。

需要注意的是,视图只是一个虚拟的表结构,不实际存储数据。因此,对视图的修改实际上会修改底层的查询逻辑,而不是直接修改数据。另外,在使用视图时,需要考虑视图的性能影响,因为视图是在查询时动态计算的,可能会对查询性能产生一定的影响。

# 数据库中删除名为 EmployeeView 的视图。应使用哪条语句?

1
DROP VIEW EmployeeView

# 分别解释一下这四个:Integer i01 = -128;int i02 = -128;Integer i03 =Integer.valueOf (-128);Integer i04 = new Integer (-128); 以及它们之间的相等关系.

Integer i01 = -128;
int i02 = -128;
Integer i03 =Integer.valueOf(-128);
Integer i04 = new Integer(-128);

“i01”:“这是一个包装类 Integer 的实例,通过赋值创建,值为 - 128.”

“i02”:“这是一个基本数据类型 int 的变量,值为 - 128.”

“i03”: “这是一个包装类 Integer 的实例,通过调用 Integer 类的 valueOf 方法创建,值为 - 128。”

“i04”: “这是一个包装类 Integer 的实例,通过调用 Integer 类的构造方法创建,值为 - 128。”,

显然,2 和其它三项都不可以比较,其中 1=3=4

# 关于协程你对它的了解?

协程,也称为微线程或轻量级线程,是用户态的轻量级线程。

# 协程的优点和缺点

协程的优点主要包括:

  1. 执行效率高:由于协程是轻量级线程,只在用户态进行操作,因此系统消耗的资源非常低,能够高效地执行任务。
  2. 无需线程上下文切换:协程的切换开销由程序自身控制,避免了线程切换带来的额外开销,因此能够提高程序的性能。
  3. 单线程多任务:协程可以在单线程中实现多任务,无需创建新的系统线程,从而降低了系统开销。
  4. 避免线程安全问题:协程中的数据共享是通过通信方式实现的,避免了线程安全问题,避免了锁竞争,使得程序更加简洁高效。

然而,协程也存在一些缺点:

  1. 系统无法感知协程的存在:协程是由用户态控制的轻量级线程,系统无法感知其存在,因此不能发挥多核 CPU 的优势,适用于 I/O 阻塞型场景,而不适用于 CPU 密集型场景。
  2. 无法实现并发执行:由于协程是单线程的轻量级线程,无法实现并发执行,因此在需要并发执行的任务中可能并不适用。
  3. 需要手动调度:协程需要手动调度,程序员必须承担调度的责任,这可能会增加程序开发的复杂性。

总的来说,协程具有执行效率高、无需线程上下文切换、单线程多任务等优点,但也存在无法发挥多核 CPU 优势、无法实现并发执行、需要手动调度等缺点。因此,在选择使用协程时,需要根据具体的应用场景和需求进行评估和选择。

# 协程间的通信

通过通道(channel)

# 关于 inode 的了解

# 守护线程的一些概念

守护线程是一种应用程序用于执行后台任务的线程。

任何一个非守护线程没有结束,守护线程就一直运行存在。

当最后一个非守护线程结束时,守护线程就会随着 JVM 一起结束运行。

GC 线程其实就是守护线程。

守护线程产生的新线程也是守护线程。


2020 年运维卷 2 15/47 答对,前 21%

# go 语言中函数的支持

函数中的 defer 语句执行的数据为先进先出

# go 中的切片特征

在 Go 语言中,切片是一种动态数组,它提供了更加灵活的方式来处理数组和数组元素。切片的特性包括以下几点:

  1. 不定长:切片可以随着存储容量的需要自动增长或缩小。这意味着切片可以根据实际需要来调整其大小,而无需在声明时指定固定的长度。
  2. 提供 append 函数:切片提供了 append 函数,用于方便地向切片中添加新的元素。这个函数使得在切片中添加元素变得简单且直观。
  3. 引用底层数组头指针:切片的本质是引用底层数组的头指针,以及当前切片长度和底层数组的大小。这意味着切片操作底层数组的效率较高,能够快速地访问和修改数组元素。
  4. 共享底层数组:切片可以共享底层数组,这意味着多个切片可以指向同一个底层数组。如果多个切片共享了同一个底层数组,那么修改其中一个切片的内容也会影响到其他切片。
  5. 扩容机制:当切片的底层数组容量不够时,切片会自动进行扩容。每次 append 操作如果容量不足,会创建一个新的数组,其大小是原数组的两倍,并将原数组的数据复制到新数组中。这样可以有效地处理数据增长的情况,避免频繁地重新分配内存。

切片在 Go 语言中广泛应用,它提供了一种方便、灵活且高效的方式来处理和管理数据集合。

# 数据链路层的功能

# 代码结果是?

1
2
3
4
5
6
7
8
9
10
11
12

#include <stdio.h>

#define CONS(x,y) (int)(x##e##y)

int main()

{

printf("%d\n", CONS(4,2));
}

解;

这段代码使用了 C 语言的预处理器宏定义和 ## 运算符。在这个代码中,CONS (x,y) 宏的功能是将 x 和 y 连接成一个字符串,并且在其前面加上 "e",然后将其转换为一个整数。因此,CONS (4,2) 将会得到 "4e2",然后转换为整数,即 4*10^2,结果为 400。所以,这段代码的输出结果为:

1
400

# Java 中的真数组

在 Java 中,真数组是一个固定大小的数据结构,它可以容纳一定数量的相同类型的元素。一旦创建了一个数组,就不能改变它的大小。数组的元素可以是任何类型,包括基本数据类型(如 int,char,boolean 等)和对象类型。

在 Java 中,你可以通过以下方式创建一个真数组:

1
2
int[] intArray = new int[10];  // 创建一个能容纳10个整数的数组
String[] strArray = new String[5]; // 创建一个能容纳5个字符串的数组

数组中的每个元素可以通过其索引进行访问。例如, intArray[0] 将访问数组中的第一个元素。在 Java 中,数组的索引是从 0 开始的,所以 intArray[0] 是数组的第一个元素, intArray[9] 是数组的最后一个元素。

真数组和 ArrayList 不同,ArrayList 是一种动态数组,它的大小可以改变。这是 Java 中两种主要的集合类型,每种类型都有其特定的使用场景。

# 关于 Linux 的防火墙

主要分为网络防火墙和主机防火墙

网络防火墙用于控制内外网的数据包通信,保护内网安全。它是在网络层工作的,针对 TCP/IP 数据包实施过滤和限制。在 Linux 系统中,防火墙体系主要基于内核编码实现,如 netfilter 和 iptables,它们分别代表了防火墙体系中的内核态和用户态。

netfilter 是 Linux 内核中实现包过滤防火墙的内部结构,不以程序或文件的形式存在,属于 “内核态(Kernel Space,又称为内核空间)” 的防火墙功能体系。

iptables 则是用来管理 Linux 防火墙的命令程序,通常位于 /sbin/iptables 目录下,属于 “用户态”(User Space,又称为用户空间)的防火墙管理体系。通过使用 iptables,外部请求在到达服务器之前首先要接受防火检查,只有通过防火墙检查,才能继续接受其他安全检查。

至于如何配置 Linux 的防火墙,从系统安装之后,可以从 “系统” 主菜单中选择 “管理” >“安全级别和防火墙” 命令来进行配置。还可以在命令行中运行命令 “system-fonfig-decuritylevel” 来定制防火墙规则。

主机防火墙是一种保护机器不受来自外部的、不需要的网络数据的干扰的方式。它允许用户通过定义一组防火墙规则来控制主机上的入站网络流量。这些规则用于对进入的流量进行排序,并可以阻断或允许流量。

在 Linux 系统中,有一个名为 firewalld 的服务,它提供了一个带有 D-Bus 接口的、动态可定制的、基于主机的防火墙。如果防火墙规则在动态修改时需要启、修改和删除,firewalld 服务能够在每次修改规则时进行这些操作,不需要在每次修改规则时重启防火墙守护进程。这种工具有易于使用、集成度高等优点。

# iptables 和 firewalld 的区别

它们是 Linux 系统中两个不同的防火墙工具,以下为它们的主要区别:

  1. 动态规则管理:firewalld 可以动态修改单条规则,动态管理规则集,允许在不破坏现有会话和连接的情况下更新规则。而 iptables 在修改规则后必须全部刷新才能生效。
  2. 规则表示方式:firewalld 使用区域和服务而不是链式规则,它基于区域和服务进行规则设置,而非传统的链式规则。而 iptables 则沿用传统的链式规则。
  3. 默认策略:firewalld 默认是拒绝的,需要设置以后才能放行。而 iptables 默认是允许的,需要拒绝的才去限制。
  4. 功能实现:无论是 firewalld 还是 iptables,它们的作用都是用于维护规则,但真正使用这些规则的是内核的 netfilter。也就是说,它们都是通过 netfilter 来实现防火墙的功能。

总的来说,iptables 和 firewalld 在功能和使用上没有本质的区别,但是在操作方式、规则管理和默认策略等方面存在一些差异。在选择使用时,可以根据自己的需求和习惯来选择更适合自己的防火墙工具。

# redis 在的有序集合中在数据量极少的情况下使用哪种结构存储方案?

压缩表

# 要授予用户读取表中数据的权限,应使用哪个命令?

要授予用户读取表中数据的权限,你应该使用 SQL 的 GRANT 命令。这是一个非常常见的数据库操作,用于赋予用户对数据库的特定权限。

例如,如果你想让用户能够读取(SELECT)一个名为 "employees" 的表,你可以使用以下命令:

1
GRANT SELECT ON employees TO your_username;

在这个命令中,"SELECT" 是你想赋予的权限,"employees" 是表的名字,"your_username" 是用户的用户名。

请注意,这个命令的执行需要数据库管理员(DBA)的权限。此外,实际的 SQL 语句可能会根据你使用的数据库管理系统(如 MySQL、PostgreSQL、Oracle 等)有所不同。

# char 和 varchar 的区别?

CHAR 和 VARCHAR 都是用于存储字符数据的 SQL 数据类型,但它们之间存在一些关键的区别。

  1. 长度:CHAR 的长度是固定的,而 VARCHAR 的长度可以变化。CHAR 的长度是在定义数据类型时确定的,并且后续不能更改。而 VARCHAR 的长度可以根据存储的需求动态调整。
  2. 存储效率:因为 CHAR 是定长,所以它在存储数据时效率较高,因为它不会浪费空间。而 VARCHAR 由于需要存储变长的数据,可能会占用更多的空间,尤其是在数据量较小的情况下。
  3. 性能:由于 CHAR 是定长的,所以在某些情况下,查询和索引性能可能会比 VARCHAR 高。因为 VARCHAR 的长度是变动的,所以在某些数据库系统中,它可能会影响到查询和索引的性能。
  4. 存储方式:在存储方式上,CHAR 和 VARCHAR 也有所不同。在 CHAR 中,一个英文字符(ASCII)占用 1 个字节,而一个汉字会占用两个字节。而在 VARCHAR 中,一个英文字符占用 2 个字节,一个汉字也会占用 2 个字节。

总的来说,CHAR 和 VARCHAR 各有其优点和适用场景。如果需要存储的数据长度固定且不会变化太大,或者对空间的效率有较高要求,可以选择使用 CHAR;如果需要存储的数据长度会变化,或者对性能有较高要求,可以选择使用 VARCHAR。

# 返回状态代码

1xx 处理信息,服务器收到请求,用户继续执行操作

2xx 请求成功,操作被成功接收并处理

3xx 重定向,服务器端需要进一步操作以完成请求

4xx 客户端错误,请求包含语法错误或无法完成请求

5xx 服务器端错误,服务器在处理请求过程中发生了错误

作者:牛客 378117799 号

链接:

https://www.nowcoder.com/exam/test/73442480/submission?pid=35396977&pageSource=testHistory

来源:牛客网

注意这里的 3XX 是服务器状态

# javap,jdb,jstack,jconsole 分别是什么

javap,jdb,jstack,jconsole 是 Java 开发中常用的工具和命令,分别用于不同的功能。

  1. javap:这是 Java 的 class 文件反编译器。它可以反编译 class 文件,从而获得类的结构信息、方法信息、常量池信息等。
  2. jdb:这是 Java 的调试器,用于调试 Java 程序。你可以使用 jdb 命令行工具,或者在 IDE 中集成 jdb 进行断点调试。
  3. jstack:这是 Java 的一个诊断工具,用于查看 Java 程序的线程堆栈信息。当 Java 程序崩溃生成 core 文件时,可以使用 jstack 工具获得 core 文件的 java stack 和 nativestack 的信息。
  4. jconsole:这是 Java Management Extensions (JMX) 的一个实时的图形化监测工具。它利用了内建到 JVM 里面的 JMX 指令来提供实时的性能和资源的监控,包括了 Java 程序的内存使用、线程的状态、类的分配状态和空间使用等等。

# 小米集团

# 下面的命令返回结果是?

user=‘whoami’

1
2
### sh test.sh
### echo $user

答案是:空值

正确获取用户名的方法是:

1
2
3
#!/bin/bash  
user=$(whoami)
echo $user

这段脚本首先使用 #!/bin/bash 来声明这是一个 bash 脚本。然后,它使用 $(whoami) 来执行 whoami 命令,并将其输出赋值给 user 变量。最后,它使用 echo $user 来打印出 user 变量的值。

你需要确保你的脚本有执行权限。你可以使用 chmod +x test.sh 来给你的脚本添加执行权限。然后,你可以使用 ./test.sh 来运行你的脚本。这将在你的终端中打印出当前用户的用户名。

# 关于 nginx 配置不涉及磁盘读写的有哪些?

proxy_cookie_path;

Nginx 的缓存配置有以下选项:

  1. proxy_cache:用于反向代理缓存后端服务器的静态内容。该指令可以指定缓存的目录、大小、过期时间等。
  2. proxy_cache_valid:用于指定不同响应代码的缓存有效时间。例如, proxy_cache_valid 200 304 12h; 表示对 200 和 304 响应的缓存有效时间为 12 小时。
  3. proxy_temp_path:用于指定缓存的临时目录。
  4. proxy_buffering:用于开启或关闭代理服务器的缓冲功能。
  5. proxy_buffers:用于指定代理服务器的缓冲区大小。
  6. proxy_busy_buffers_size:用于指定代理服务器的忙碌缓冲区大小。
  7. proxy_max_temp_file_size:用于指定代理服务器的最大临时文件大小。
  8. proxy_temp_file_write_size:用于指定代理服务器的临时文件写入大小。
  9. proxy_cache_lock:用于控制是否锁住缓存的访问,以避免并发修改。
  10. proxy_cache_revalidate:用于控制是否在缓存过期时重新验证缓存的有效性。
  11. proxy_cache_background_updates:用于控制是否允许在后台更新缓存内容。
  12. proxy_cache_bypass:用于控制是否绕过缓存,直接向后端服务器发送请求。
  13. proxy_no_cache:用于控制是否将特定的请求缓存起来。
  14. proxy_cache_min_uses:用于指定缓存被使用多少次后才被考虑为命中和未命中的依据。

以上是 Nginx 缓存配置中常用的选项,根据实际需求可以进行适当的配置和优化。

# grep 查看以 “.log” 为开始的文件

1
grep -r "^\.log" /path/dir

# 原因分析?

[host@test ~]# ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.023 ms
[host@test ~]# telnet 10.0.0.1 666
Trying 10.0.0.1 …
telnet: connect to address 10.0.0.1 : Connection refused
telnet 提示 Connection refused 的可能是什么 s

1、10.0.0.1 机器的 666 端口上服务不正常

2、telnet 不能检测 udp 协议端口

3、10.0.0.1 机器的防火墙限制了 666 端口的访问

2022 运维开发 卷一

# 哪个命令可以用于创建 Linux 文件系统?

答:mkfs

拓展:fdisk》用于创建和维护分区表的程序

​ mount》用于挂载 Linux 系统外的文件

​ fsck》检查文件系统并尝试修复错误

# 某机器字长 64 位,内存容量位 12GB, 按字编址,则可寻址范围为?

12*1024 * 8 / 64 = 1536M

# 哪个命令来统计文件中包含的行数、字数、字符总数

答:wc

扩展:

1、stat 命令用于显示文件的状态信息,比如文件的权限、所属用户和组、大小、修改时间等信息

2、ls 命令用于列出指定目录下的文件和子目录

3、tail 命令用于查看文本文件的尾部内容,默认显示文件的最后 10 行

# 哪一个命令可以用于侦测 OSI 网络模型中 7 层服务的健康状态?

答:curl

拓展:

1、ping 用于测试网络连接量和分析网络速度

2、telent 远程连接命令

3、nmap 扫描网络中处于活动状态的主机、开放端口、操作系统和服务检测信息的扫描

注:ping 命令使用 ICMP 协议探测网络状态

ARP 地址解析协议属于 TCP/IP 模型中的 IP 层。

# 由操作系统的加载程序执行的操作有?

操作系统的加载程序(也称为引导加载程序或引导程序)在启动过程中执行一系列操作,以准备操作系统的运行环境。这些操作可能包括:

  1. 硬件初始化:加载程序可能会初始化一些基本硬件,如内存、显示器、键盘等。
  2. 自检:许多加载程序会执行基本的硬件自检程序,以确保所有的硬件都能正确工作。
  3. 启动设备选择:加载程序可能会检测并选择一个启动设备,如硬盘、U 盘或网络。
  4. 引导扇区加载:加载程序通常会从选定的启动设备上加载引导扇区(也称为引导扇区或启动扇区)。
  5. 内核加载:引导扇区中的代码通常会进一步加载操作系统的内核。这可能涉及到从硬盘读取内核映像,并将其加载到内存中。
  6. 设置启动参数:加载程序可能会设置一些启动参数,这些参数将被传递给内核,以影响其行为和配置。
  7. 切换到内核:一旦内核被加载并设置好参数,加载程序就会将控制权交给内核,开始执行操作系统的主要功能。
  8. 启动其他服务:在某些情况下,加载程序可能还会启动一些其他服务,如初始化系统配置、启动后台进程等。

请注意,不同的操作系统和硬件平台可能会有不同的加载程序和执行的操作。上述步骤是一个通用的描述,具体的细节可能会有所不同。

# 有两台 nginx 服务器 n0 和 n1,需要将 n0 的 nginx access log 同步到 n1 ,可以使用下面哪些服务有?

  1. Rsync:Rsync 是一种用于在本地和远程系统之间同步文件的工具。您可以使用 Rsync 在 n0 和 n1 之间同步 nginx access log。
  2. SCP(Secure Copy):SCP 是一种基于 SSH 的文件传输协议,可以在本地和远程系统之间安全地传输文件。您可以使用 SCP 将 n0 的 nginx access log 复制到 n1。
  3. FTP(File Transfer Protocol):FTP 是一种用于在本地和远程系统之间传输文件的协议。您可以使用 FTP 将 n0 的 nginx access log 上传到 n1。
  4. Syslog:Syslog 是一种用于在本地和远程系统之间传输日志消息的协议。您可以将 n0 的 nginx access log 发送到 Syslog 服务器,然后将其转发到 n1。

# 用于服务发现的软件有?

DNS、Zookeeper、Consul、ETCD

# 私有地址:

A 类:10.0.0.0~10.255.255.255 10 开头的

B 类:172.16.0.0~172.31.255.255

C 类:192.168.0.0~192.168.255.255

2022 运维开发卷 2

# 查看 Linux 系统 inode 的使用率,并格式化输出?

df -i 或者 df -hi

# 一个事务在数据库中完全 Commit 或 Rollback 属于 ACID 中的哪一个属性?

原子性和持久性。

# Redis 中遍历所有 Key,哪种方式对 Redis 服务影响最小?

说说 keys*, 这个命令会阻塞 Redis 服务器,因为会把所有的 key 都检索出来,所以这种方式对 Redis 服务影响最大

而 scan 命令是一个渐进式的遍历命令,可以遍历所有的 key,但对服务影响小。所谓渐进式就是每次只返回少量的元素。

# Linux 系统中,抓取 eth2 网卡上经过的数据包,已知对方 IP 为 10.136.9.14,TCP 端口为 80,对应的命令为?

在 Linux 系统中,你可以使用 tcpdump 命令来抓取指定网卡上的数据包。对于你的需求,可以使用以下命令来抓取 eth2 网卡上对方 IP 为 10.136.9.14 且 TCP 端口为 80 的数据包:

1
sudo tcpdump -i eth2 -s 0 -A 'host 10.136.9.14 and port 80'

这个命令的含义如下:

  • sudo :使用管理员权限执行命令。
  • tcpdump :抓包命令。
  • -i eth2 :指定网卡为 eth2。
  • -s 0 :抓取完整的数据包,而不截断数据。
  • -A :以 ASCII 格式显示数据,方便阅读。
  • 'host 10.136.9.14 and port 80' :过滤条件,只抓取对方 IP 为 10.136.9.14 且 TCP 端口为 80 的数据包。

请注意,执行该命令可能需要管理员权限,并且你需要在有 root 权限的情况下运行它。

# shell 变量名的命名规则是?

1、以字母或者下划线开头

2、可以包含字母、数字、下划线

3、区分大小写

4、不应该与 Shell 的关键字和命令名重复

# Linux '/tmp’目录的权限是什么?

1777

# 哪些文件系统类型是 Linux 默认支持的?

Linux 默认支持许多类型的文件系统,其中一些最常见的文件系统类型包括:

  1. Ext4:这是目前 Linux 发行版中最常用的文件系统类型,是 Ext3 文件系统的后续版本,具有更大的文件系统和文件、更多的子目录数量以及持久性预分配等特点。
  2. ReisferFS:这是一种高级的文件系统类型,旨在为 NFSv4 提供更好的支持,同时具有日志记录和数据完整性检查功能。
  3. XFS:这是一种高性能的文件系统类型,最初是为 OS/2 开发的,但后来被移植到 Linux 系统中。它具有优秀的磁盘管理和性能优化特点。
  4. Btrfs:这是一种新型的、具有快照和容错能力的文件系统类型,可以很好地适应大容量存储设备。
  5. JFS:这是一种支持透明压缩和日志记录的文件系统类型,具有优秀的性能和稳定性。

总的来说,Linux 支持的文件系统类型非常多,可以根据不同的需求选择最适合的文件系统类型。

# 标准 Http 协议不支持的请求方法有?

update、drop、insert

# 在 MySQL 数据库中,哪种操作不能通过 Binlog 恢复,Binlog 是 row 格式

在 MySQL 数据库中,Binlog(二进制日志)用于记录数据库的所有更改操作,以便在需要时进行恢复。然而,有些操作是无法通过 Binlog 恢复的,主要包括以下几种:

  1. 创建或删除数据库:使用 Binlog 无法恢复已删除的数据库或创建新的数据库。
  2. 创建或删除表:类似于数据库的创建和删除,Binlog 无法恢复已删除的表或创建新的表。
  3. 修改表结构:更改表的列名、数据类型、索引等操作无法通过 Binlog 恢复。
  4. 更改存储引擎:将表从一个存储引擎更改为另一个存储引擎的操作无法通过 Binlog 恢复。
  5. 更改数据表的字符集:更改表的字符集或排序规则的操作无法通过 Binlog 恢复。
  6. 更改表的行格式:例如,将表的行格式从 ROW 更改为 STATEMENT 或 MIXED,无法通过 Binlog 恢复。

需要注意的是,上述操作虽然无法通过 Binlog 恢复,但是可以通过备份和还原的方式来恢复数据。因此,为了确保数据的安全性,建议定期备份数据库,并在执行重要操作之前先做好备份。

# 在 Linux 运维工作中,我们经常用 top 或 uptime 命令来观察系统的平均负载(Load Average),谈谈你对平均负载理解?

在 Linux 运维工作中,理解平均负载的概念确实非常重要。平均负载是描述系统在特定时间内,待处理的工作负载的平均水平。它可以帮助我们了解系统的繁忙程度,以及系统资源是否得到充分利用。

首先,我们先来看一下平均负载的来源。在 Linux 中,平均负载可以通过 top 或 uptime 命令来查看。uptime 命令会显示系统的当前时间、已经运行的时间、登录的用户数,以及系统在过去 1 分钟、5 分钟和 15 分钟内的平均负载。

然而,我们经常会误解平均负载的含义。平均负载并不直接代表单位时间内的 CPU 使用率。事实上,平均负载反映的是在特定时间段内,等待 CPU 处理的任务的平均数量。这包括那些正在等待 CPU 时间片,以及那些已经因为 I/O 操作或主动进入等待状态而离开运行队列的进程。

换句话说,平均负载可以理解为系统在特定时间段内,处于 “待处理” 状态的进程的平均数量。如果一个进程满足以下条件,它就会处于运行队列中:没有在等待 I/O 操作的结果,没有主动进入等待状态,也没有被停止。

对于运行队列中的平均进程数量的理解,我们不能简单地把它当做 CPU 的当前活动进程数。一般来说,只要每个 CPU 的当前活动进程数不大于 3,那么系统的性能就是良好的。如果每个 CPU 的任务数大于 5,那么就表示这台机器的性能有严重问题。

在实际的 Linux 运维工作中,理解平均负载的概念可以帮助我们更好地把握系统的繁忙程度,以及预测系统可能面临的性能问题。同时,这也要求我们不断地学习和理解更深层次的系统架构和原理。


# 金山办公

2020 校招卷一

# Linux 文件权限的分类

Linux 文件一共有 10 位的长度,分成 4 段。

第一段一个位置,代表文件的类型

第二段三个位置,代表主权限

第三段三个位置,代表属组权限

第四段三个位置,代表其它用户权限

# init 命令了解吗?

它相当于父进程。

init 是 Linux 系统操作中不可缺少的程序之一。所谓的 init 进程,它是一个由内核启动的用户级进程。 init 进程由 0 进程创建,完成系统的初始化,是系统中所有其他用户进程的祖先进程。
  内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序 init 的方式,完成引导进程。所以, init 始终是第一个进程(其进程编号始终为 1)。
  Linux 中的所有进程都是由 init 进程创建并运行的。首先 Linux 内核启动,然后在用户空间中启动 init 进程,再启动其他系统进程。在系统启动完成后, init 将变成为守护进程监视系统其他进程。
  内核会在过去曾使用过 init 的几个地方查找它,它的正确位置(对 Linux 系统来说)是 /sbin/init 。如果内核找不到 init ,它就会试着运行 /bin/sh ,如果运行失败,系统的启动也会失败。

# 在 bash 中 export 命令的作用是

创建一个环境变量,并对其子 shell 可见。没有用 export 声明的变量,仅对当前的 shell 可见。
注:它不是为其它应用程序设置环境变量的。

# 试着写几种查看 file1 文件的第 300-500 行的内容的 linux 命令

使用 sed 命令;

1
sed -n '300,500p' file1

使用 awk 命令;

1
awk 'NR>=300 && NR<=500' file1

使用 head 和 tail 命令;

1
head -n 500 file1 | tail -n +300

# head 和 tail 命令的区别?

head 命令和 tail 命令都是用于查看文件内容的命令,它们的主要区别在于所查看的文件部分不同。

head 命令用于查看文件的开头部分,默认显示前 10 行内容,可以通过一个数字选项来设置显示的行数。例如, head -20 install.log 会查看 install.log 这个文件前面 20 行的内容。

tail 命令则用于查看文件的末尾部分,默认显示文件的最后 10 行内容。同样,也可以通过一个数字选项来设置显示的行数。例如, tail -20 install.log 会查看 install.log 这个文件最后 20 行的内容。

如果想要查看正在改变的日志文件,比如及时观察 /var/log/messages 的变化,可以使用 tail -f /var/log/messages 命令,该命令会自动实时地把打开文件中的新消息显示到屏幕上。

综上, head 命令和 tail 命令虽然都是用于查看文件内容的命令,但它们所查看的文件部分不同,同时, tail 命令还具有实时查看更新内容的功能。

# python 组合数据类型。

(在 python 中引发一个不存在索引的列表元素会出现 NameError 错误)

(在 python3 版本中,支持使用中文名作为变量名,而在 python2 中不可以)

# [3] in [1,2,3,4] 的结果是?

False

想要结果是 True 就得是 3 in [1,2,3,4]

# python 中字典对象的什么方法返回字典中的 “键 - 值对” 列表

items () 方法

# python 中内建异常类的基类是?

BaseException

# python 中列表和元组的区别是?

列表可变,元组不可变,列表比元组要慢一点。

# 计算出从你生日之日起到今天一共过了多少天?(python、go、shell 均可)

1
2
3
4
5
6
7
8
9
10
11
12
from datetime import datetime

#你的生日
birthday = datetime(2001,1,1)

#现在的日期
today = datetime.today()

delta = today - birthday

days = delta.days
print(f"{days}")

# 你如何监视服务器质量和网络质量?用哪些工具及优缺点?

监视服务器质量和网络质量的重要性不言而喻。这可以通过一系列的工具和方法来实现。

一般来说,对于服务器质量的监控,可以使用 Nagios、Zabbix 等工具,它们是用于监控整个基础结构的工具,可以监控几乎所有内容,比如服务器性能,网络性能以及协议,操作系统,应用等等。不过,对于一些企业基础架构没那么复杂,或者只需要监控服务器性能的情况,也可以使用轻量级的工具如 Ward 来监控服务器状况,Ward 可以提供与服务器有关的主要信息。

对于网络质量的监控,现在有很多种工具可供选择。一种是基于服务器端的监测,这种监测软件需要用户购买后安装在本地服务器上,主要监测本地的服务器、数据库等软硬件的运行性能。优点是用户可以了解本地机器的使用效率,还可以了解本地的网络连接及一些电子商务流程在本地的执行情况。但缺点是不能直接反映终端用户登录网站及使用网站提供的电子商务服务的实际体验。另一种是离线分析工具,比如 Etherman 等,它们是在线实时监测工具的补充,可以对网络状态做更细致、更精确的测量和分析。

最后要强调的是,这些工具各有利弊,不同的场景需要使用不同的工具,所以并没有一种万能的工具可以适用于所有情况。在使用这些工具的时候,一定要结合实际需求和场景,选择最适合自己的工具来提高工作效率。

# 说说你理解的运维开发工程师是什么样的一个角色?并说说运维开发工程师应该具备哪些技能?

运维开发工程师是一种负责开发、维护和管理企业 IT 基础设施的工程师角色。他们需要具备广泛的计算机科学和系统工程知识,以及丰富的实践经验,以应对现代企业 IT 环境的复杂性和多样性。

运维开发工程师的主要职责包括:

  1. 系统设计与优化:运维开发工程师需要了解系统架构设计,包括服务器、存储、网络等基础设施的规划、部署和故障排除。他们还需要对应用程序的性能进行优化,以改善系统的整体性能。
  2. 监控与故障排除:运维开发工程师需要设计和实施监控系统,以便及时发现和解决潜在的问题。当系统出现故障时,他们需要迅速响应并采取适当的措施以最大限度地减少对业务的影响。
  3. 安全防护:运维开发工程师需要了解网络安全的基本概念和方法,并确保系统免受恶意攻击和未经授权的访问。他们还需要定期更新和实施安全补丁和策略,以确保系统的安全性。
  4. 自动化与工具开发:为了提高工作效率和减少人为错误,运维开发工程师需要开发和维护自动化工具和脚本,以简化日常任务和加快故障排除速度。
  5. 容量规划和管理:运维开发工程师需要了解系统的容量需求,并根据业务需求进行规划和管理。他们需要确保系统具有足够的处理能力和存储空间,以满足用户的需求并保证良好的用户体验。

为了完成这些职责,运维开发工程师需要具备以下技能:

  1. 操作系统和网络知识:运维开发工程师需要了解常见的操作系统和网络协议,以便进行系统的部署、配置和故障排除。
  2. 编程和脚本语言:编程和脚本语言是开发自动化工具和脚本的关键。常见的编程语言包括 Python、Java、C++ 等,而脚本语言则包括 Bash、Perl、Python 等。
  3. 数据库管理技能:数据库是现代应用程序的重要组成部分,因此运维开发工程师需要具备数据库管理技能,包括安装、配置、优化和维护数据库等。
  4. 监控和日志分析技能:为了确保系统的稳定性和可用性,运维开发工程师需要了解监控和日志分析技能,包括使用工具(如 Nagios、Zabbix 等)监控系统性能、识别问题并分析日志文件等。
  5. 安全知识和技能:运维开发工程师需要了解常见的网络安全威胁和攻击手段,并掌握防范措施。他们还需要掌握加密技术和访问控制策略的实施方法,以确保系统的安全性。
  6. 学习能力:IT 行业的变化非常快,因此运维开发工程师需要具备快速学习和适应新技术的能力,以便应对不断变化的 IT 环境。
  7. 沟通和团队合作能力:运维开发工程师需要与其他团队(如开发、测试、QA 等)紧密合作,以确保系统的稳定性和可用性。他们还需要与业务团队合作,以了解业务需求并为其提供技术支持。因此,良好的沟通和团队合作能力是必不可少的。

2020 运维卷二

# chmod 命令的了解

# 网易

2021 系统运维(正式第一批)

# Linux 进程调度的时候,什么进程状态转化不会发生?

D-》T 不可中断阻塞 -》挂起

几个简记:

R (running): 运行或者就绪

D (disk sleep): 不可中断阻塞

S (sleeping): 可中断阻塞

T (stopped): 挂起

# 服务器上有 aa.sh,bb.sh, 确认脚本编写语法没有问题,执行 bash aa.sh || bash bb.sh 的时候,是什么意思?

答:aa.sh 执行不成功,执行 bb.sh

注: command1 || command2 逻辑 --> 如果这个命令执行失败了 || 那么就执行这个命令
command1 && command2 逻辑 --> 如果这个命令执行成功 && 那么执行这个命令

# server 端接受 TCP 包的时候,发现 1,2,3,4,5 顺序中丢了 2,会触发什么?

此题设计的考点为快重传。

接收端在接收到报文段 1 和报文段 2 后都发出了确认,但是没收到报文段 3 就收到了报文段 4,它会重复发送报文段 2 对应的 ack 码,再收到报文段 5,报文段 6 之后仍然会发送报文段 2 的 ack 码,这样发送端连续收到 3 个重复的 ack 码时,就能很快速的意识到报文段 3 丢失了,会重新发送报文段 3

# bash 下如何获得当前进程的 pid?

答:echo $$

拓展:

echo $$ 返回登录 shell 的 PID

echo $? 返回上一个命令的状态,0 表示没有错误,其它任何值表明有错误

echo $# 返回传递到脚本的参数个数

echo $* 以一个单字符串显示所有向脚本传递的参数,与位置变量不同,此选项参数可超过 9 个

echo $! 返回后台运行的最后一个进程的进程 ID 号

echo $@ 返回传递到脚本的参数个数,但是使用时加引号,并在引号中返回每个参数

echo $- 显示 shell 使用的当前选项

echo $0 是脚本本身的名字

echo $_ 是保存之前执行的命令的最后一个参数

echo $1 传入脚本的第一个参数

# linux 下管道数据进出是哪种模式?

答:fifo, 即 First In First Out 先进先出

# 如果在 Linux 下执行对一个可执行文件,执行 chmod u+s /usr/local/bin/htg,有什么副作用?

文件提权

解释:

在 Linux 中, chmod u+s 命令将给文件的所有者添加 “setuid” 权限。当一个程序具有 setuid 权限时,每当该程序运行时,它将以该文件的所有者的身份运行,而不是以运行它的用户的身份运行。

例如,如果你执行的 htg 程序是一个命令行工具,那么当你执行它时,它会以 /usr/local/bin/htg 文件的所有者的权限运行,而不是以你的用户的权限运行。

副作用包括:

  1. 安全问题:Setuid 权限可能被滥用,导致系统安全问题。例如,如果 htg 程序存在漏洞,攻击者可能会利用这些漏洞,通过运行 htg 程序获得文件所有者的权限,这些权限可能超出他们本应有的权限。
  2. 权限问题:如果 htg 程序需要以特定用户的身份运行(例如,文件的所有者),那么添加 setuid 权限可能会解决问题。然而,这也可能导致其他用户无法正常运行 htg 程序,因为他们可能没有足够的权限。
  3. 程序运行问题:如果 htg 程序依赖于特定的用户环境或配置文件,并且这些文件对所有用户都不可用,那么添加 setuid 权限可能会导致程序无法正常运行。

总的来说,添加 setuid 权限是一个需要谨慎操作的操作,需要充分理解其含义和可能带来的问题。在大多数情况下,你应该尝试以其他方式解决程序运行的问题,而不是添加 setuid 权限。如果你确实需要添加 setuid 权限,那么你应该确保程序的安全性,并确保你理解这可能带来的安全风险。

# 网卡丢包情况可以用哪个命令查看?

ifconfig

可以直接查看到 eth0 等网卡的情况

# 文件系统启用 journal 的作用?

journal 文件系统是一个文件系统用于追踪没有 dump 到文件系统的修改,然后可以在故障时帮助文件系统找回丢失的文件。

linux fsck (file system check) 用于检查和修复 Linux 档案,同时检查一个或多个 Linux 档案文件系统。

# 编写脚本,找出 /usr/src 目录下所有的.c 文件,然后将这些.c 文件打包成一个 tgz 文件

find /usr/src -name “.c” -type f -print0 | tar -czvf backup.tar.gz --null -T - 或者 find /usr/src -name “.c” -type f -exec tar -czvf backup.tar.gz ‘{}’ + #重点是考察 find/tar 命令的参数使用

# 查走某目录下的.c 文件并列举出来

1
find /root/usr -type f -name "*.c"

# 如何在非图形界面下抓取来自 eth0 的目标地址为 123.13.1.3 的 80 端口 tcp 数据包,对应的 tcpdump 命令怎么写?

要使用 tcpdump 命令在非图形界面下抓取来自 eth0 的目标地址为 123.13.1.3 的 80 端口 TCP 数据包,可以使用以下命令:

1
2
sudo tcpdump -i eth0 -s 0 -A 'host 123.13.1.3 and port 80'

这个命令的意思是:

  • -i eth0 :监听 eth0 网络接口。
  • -s 0 :抓取完整的数据包,而不截断数据。
  • -A :以 ASCII 格式打印数据包的数据部分。
  • 'host 123.13.1.3 and port 80' :只抓取目标地址为 123.13.1.3 且端口为 80 的数据包。

请注意,执行此命令可能需要管理员权限,因此需要使用 sudo 或在 root 用户下执行。

# 请描述运维的工作内容及核心目标,为达成目标最需要具备的因素有哪些?

运维工作主要是指对计算机系统、网络、数据库等进行维护、监控和管理,以确保系统的稳定运行和业务的持续服务。以下是运维的主要工作内容和核心目标:

工作内容:

  1. 系统监控和维护:监控服务器、网络、存储等基础设施的运行状态,及时发现和解决性能瓶颈、安全问题等。
  2. 故障处理:在系统出现故障时,快速定位并解决问题。这包括定期的服务器巡检、日志分析、应急预案等。
  3. 资源规划和管理:合理规划和分配服务器、存储、网络等资源,提高系统的可用性和稳定性。
  4. 数据备份和恢复:确保数据的安全性和完整性,定期进行数据备份,在数据丢失时能够快速恢复。
  5. 优化和改进:通过对系统的性能监控、分析和优化,提高系统的运行效率。

核心目标:

  1. 高可用性:确保系统能够持续、稳定地为用户提供服务,减少停机时间。
  2. 安全性和隐私保护:保护系统和数据的安全,防止黑客攻击和数据泄露。
  3. 性能优化:提高系统的性能和响应速度,提升用户体验。
  4. 成本控制:在满足业务需求的同时,合理控制 IT 成本。

为了达成以上目标,运维人员需要具备以下因素:

  1. 技术能力:熟悉服务器、网络、存储等基础设施的配置和管理,了解操作系统、数据库等软件系统的基本原理和操作。
  2. 问题解决能力:能够快速定位和解决系统出现的各种问题,这包括对日志的分析、系统性能的监控和优化等。
  3. 沟通能力:与开发、测试、市场等部门保持良好的沟通,理解业务需求,提供有效的 IT 解决方案。
  4. 责任心和耐心:对工作认真负责,能够处理长时间、繁琐的任务,保证系统的稳定运行。
  5. 学习能力:不断学习和掌握新的技术和工具,以适应不断变化的市场需求。
  6. 团队合作:良好的团队合作能力,能够与其他运维人员、开发人员等协同工作,共同解决问题。
  7. 应急预案:制定和执行应急预案,在突发问题出现时能够快速响应和处理,最大限度地减少对业务的影响。
  8. 文档能力:良好的文档编写能力,能够对系统的配置、操作等进行记录和整理,为后续工作提供参考。
  9. 自动化和智能化:通过自动化工具和智能化手段提高运维效率和质量,减少人工操作误差。
  10. 合规性和安全性:了解和遵守 IT 行业的合规性要求,保证运维工作的合法性和安全性。

以上是运维工作的一些基本内容和目标,以及达成这些目标所需的因素。随着云计算、大数据等技术的不断发展,运维工作也在不断变革和创新,需要不断学习和进步。

# 讲述一下 4/7 层负载均衡的区别和适用场景。

四层负载均衡和七层负载均衡的主要区别在于它们工作的网络层和负载均衡的机制。

四层负载均衡,主要是基于 TCP 协议报文,可以处理任何基于 TCP/IP 协议的软件的负载均衡。它主要基于 IP 地址和端口号来进行服务分发,因此,对于像 HTTP、FTP 等协议,它可以实现精准的负载均衡。此外,由于 TCP 协议的传输特点,四层负载均衡可以实现较为灵活的负载均衡策略,例如,根据网络流量、负载情况等因素进行动态调整。

七层负载均衡,又称为应用层负载均衡,主要工作在 OSI 模型的应用层,它可以基于虚拟的 URL 或其他应用层信息(如浏览器类别、语言)进行负载均衡。因此,对于 Web 服务器等应用,七层负载均衡可以提供更为精细和智能的负载均衡策略。例如,通过对 URL 的分析,将不同类型的请求分发到不同的服务器上;或者根据浏览器的类型和语言,提供不同的内容版本。

至于适用场景,四层负载均衡适用于对网络协议和数据传输有较高要求的环境,例如金融、电商等需要对数据进行快速、稳定传输的场景。而七层负载均衡则更适合对应用层有较高要求的环境,例如 Web 应用、游戏服务器等需要对请求进行更精细处理和分发的场景。

# 注意点

1、OpenSSL 是一个加密软件

2、crontab 文件为时间域文件,排列方式为:MIN HOUR DAY MONTH DAYOFWEEK COMMAND

3、cat -n file1 file2 命令是把文件 file1 和 file2 连在一起,然后输出到屏幕上

4、Python 对文件的写操作方法的是 write ()、writelines ()、 append ()、open ().

5、do 不是 python 的保留字

6、elif 不可以单独使用

7、3+4j 和 3+4J 是 python 的表达式,复数

8、python 字典中的 “键” 可以是元组

9、python 中万物都可称为对象

10、在异常处理结构中,不论是否发生异常,finally 子句中的代码总是会执行的。

11、字符串编码格式 GBK 使用 2 个字节表示一个汉字,UTF-8 是 3 个字节

12、Python 用来访问和操作内置数据库 SQLite 的标准库是 sqlite3

# 如何在 Python 中实现多线程?

1、Python 有一个 multi-threading 包,但是如果你想让 multi-thread 加速你的代码,那么使用它通常不是一个好主意。

2、 Python 有一个名为 Global Interpreter Lock (GIL) 的结构。 GIL 确保只有一个 “线程” 可以在任何时候执行。一个线程获取 GIL,做一点工作,然后将 GIL 传递到下一个线程。

3、 这种情况很快发生,因此对于人眼看来,您的线程似乎并行执行,但它们实际上只是轮流使用相同的 CPU 核心。

所有这些 GIL 传递都增加了执行的开销。这意味着如果您想让代码运行得更快,那么使用线程包通常不是一个好主意。

# 这是什么意思: *args,**kwargs?我们为什么要用呢?

我们用 args 当我们不确定将多少个参数传递给函数时,或者我们是否要将存储的列表或参数元组传递给函数时。**kwargs 当我们不知道将多少关键字参数传递给函数时,或者它可以用于将字典的值作为关键字参数传递时使用。标识符 args 和 kwargs 是一个约定,你也可以使用 bob 和 **billy,但这不是明智之举.

# 讲述你如何做系统优化,提高系统性能,充分利用资源?

系统优化和性能提升是一个复杂的任务,需要综合多种策略和技术。以下是我进行系统优化,提高系统性能,充分利用资源的一些常见做法:

  1. 硬件升级:提升硬件性能是系统优化的一个重要步骤。例如,如果内存不足,可能引发许多性能问题,如程序运行缓慢、系统崩溃等。因此,根据系统的需求和预算,适时地升级硬件是必要的。
  2. 操作系统优化:使用适合的操作系统版本,关闭不必要的服务,只安装必要的程序和库,都能提高系统性能。此外,定期清理系统垃圾文件也能保持系统的流畅性。
  3. 磁盘优化:磁盘是计算机的主要存储设备,对其进行合理的使用和优化能显著提升系统性能。例如,使用 SSD(固态硬盘)可以显著提升系统的启动速度和响应速度。此外,定期清理磁盘上的冗余文件和垃圾数据也能释放磁盘空间,提高系统的运行效率。
  4. 网络优化:如果你的系统经常需要访问网络,那么网络优化也是非常重要的。使用高速的网络设备,关闭不必要的网络服务,定期清理网络缓存,都能提升网络效率。
  5. 使用高效的软件工具:使用高效的软件工具可以显著提升工作效率。例如,使用命令行工具代替图形界面的工具可以节省系统资源,使用压缩软件可以减小文件的大小。
  6. 学习和使用最佳实践:很多资源管理和优化的最佳实践都已经存在,学习和使用这些最佳实践可以避免走弯路。例如,学习如何有效地使用多核处理器,如何配置内存管理等。
  7. 监控和分析系统性能:使用系统监控工具(如 Linux 的 top 命令、Windows 的任务管理器等)和性能分析工具(如 Windows 的 Performance Monitor 等),可以实时了解系统的运行状态和性能表现,及时发现并解决性能问题。
  8. 定期维护:定期进行系统维护,包括清理临时文件、整理硬盘碎片、更新系统和软件等,可以帮助系统保持最佳的运行状态。
  9. 合理配置虚拟化技术:如果使用虚拟化技术(如 Docker 容器、虚拟机等),需要合理配置资源,避免资源浪费或过载。
  10. 节能策略:根据实际需要配置节能策略,如关闭无用的 USB 设备,设置合适的屏幕亮度,都能帮助节省能源和资源。

在进行系统优化时,需要综合考虑各种因素,包括硬件资源、软件资源、网络资源、用户需求等。只有在全面理解并考虑这些因素的情况下,才能达到最佳的优化效果。


# 必写算法题 - 出现频率很高

# 动态规划题

爬楼梯原题:

假设你在爬楼梯,需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package algorithm.other;

/*
* @Author: jun
* @Date:2023/9/17 12:29
* @概述:爬楼梯
*/
public class plt001 {
//1、确定dp数组以及下标的含义
//dp[i]:爬到第i层楼梯,有dp[i]种方法
//2、确定递推公式
//dp[i] = dp[i-1] + dp[i-2]
//3、dp数组初始化
//dp[0] = 1,dp[1] = 1 , dp[2] = 2

private static int plt(int n){
if (n < 2) {
return n;
}
int a = 1 , b = 1 , c = 0;
for (int i = 1; i < n; i++) {
c = a + b;
a = b;
b = c;
}
return c;
}

public static void main(String[] args) {
int n = 2;
System.out.println(plt(n));

}
}

出现 - 小米 - 2022 运维开发 - 大白兔奶糖取法

问题描述:

假设你有 n 个大白兔奶糖,每次最多拿走一个或者两个,你有多少种不同的方法拿完全部的大白兔奶糖?(注意求解方法的时间复杂度)

输入描述:

大白兔奶糖的个数 n (1<=n<=50)

输出描述:

拿完全部的大白兔奶糖的方法数

输入样例:

2

输出样例:

2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package algorithm.other;

/*
* @Author: jun
* @Date:2023/9/17 12:40
* @概述:
*/
public class dbt {

private static int test(int n){
if (n < 2) {
return n;
}
int a = 1 , b = 1, c = 0;

for (int i = 1; i < n; i++) {
c = a + b;
a = b;
b = c;
}
return c;
}

public static void main(String[] args) {
int n = 5;
System.out.println(test(n));
}
}


# 合并链表

合并两个有序链表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
if (l1.val <= l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}


使用了递归的方式将两个有序链表进行合并。首先判断两个链表是否为空,如果其中一个为空,就直接返回另一个链表。然后比较两个链表的头结点的值,将值较小的节点作为合并后新链表的头结点,并将原始链表中的指针指向剩余部分的合并结果。最后返回合并好的链表即可。

需要注意的是,上述方法的时间复杂度为 O (m + n),其中 m 和 n 分别是两个链表的长度。