同步、异步、阻塞、非阻塞怎么理解?

典型回答 同步与异步描述的是被调用者的。 譬如A调用B。 如果是同步,B在接到A的调用后,会立即执行要做的事。A的本次调用可以得到结果。 如果是异步,B在接到A的调用后,不保证会立即执行要做的事,但是保证会去做,B在做好了之后会通知A。A的本次调用得不到结果,但是B执行完之后会通知A。 阻塞与非阻塞描述的是调用者的。 A调用B。 如果是阻塞,A在发出调用后,要一直等待,等着B返回结果。 如果是非阻塞,A在发出调用后,不需要等待,可以去做自己的事情。 同步不一定阻塞,异步也不一定非阻塞。没有必然关系。 举个简单的例子,老张烧水: 老张把水壶放到火上,一直在水壶旁等着水开。(同步阻塞) 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞) 老张把响水壶放到火上,一直在水壶旁等着水开。(异步阻塞) 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞) 1和2的区别是,调用方在得到返回之前所做的事情不一样。一个是一直等着结果返回,一个是不需要等待。 1和3的区别是,被调用方对于烧水的处理不一样,一个是烧开了就完事儿了,一个是烧开了会主动通知。

March 22, 2026 · 1 min · santu

计算机打开电源操作系统做了什么_

典型回答 加载BIOS:当计算机插上电源时,计算机主板的BIOS开始工作。BIOS会进行POST(Power-On Self-Test)自检,检测计算机的硬件是否正常,包括处理器、内存、硬盘、显卡、网卡等设备。如果有问题,则会在屏幕上显示错误信息。 加载引导程序:当自检完成后,BIOS会从预设的启动设备(如硬盘、光盘、U盘等)中加载操作系统的引导程序。 初始化内核:引导程序会进一步加载操作系统内核和文件系统等组件,操作系统内核(kernel)是操作系统的核心组件,它负责管理计算机的各个部分、处理系统调用和线程调度等。一旦内核被找到并加载,操作系统就开始初始化内核,并设置必要的数据结构和内核变量。 加载设备驱动程序:设备驱动程序是操作系统中的一部分,负责控制计算机中的各种硬件设备,如硬盘、显卡、网卡等。操作系统会加载相应的设备驱动程序,使得这些硬件设备可以正常工作。 启动系统服务:启动系统服务,如网络服务、远程登录服务、防火墙服务等,以满足计算机在不同环境下的需求。 一旦启动完成,操作系统就进入了空闲状态,等待用户的输入或任务的到来。

March 22, 2026 · 1 min · santu

如何理解select、poll、epoll?

典型回答 select, poll, 和 epoll 都是 Linux 中常见的 I/O 多路复用技术,它们可以用于同时监听多个文件描述符(file descriptor,后文简称fd),当任意一个文件描述符就绪时,就能够非阻塞的读写数据。 select 是最原始的 I/O 多路复用技术,它的缺点是最多只能监听 1024 个文件描述符。 poll 在 select 的基础上增加了支持监听更多的文件描述符的能力,但是复杂度随着监听的文件描述符数量的增加而增加。 epoll 在 poll 的基础上进一步优化了复杂度,可以支持更多的文件描述符,并且具有更高的效率。 select 函数签名如下: 1 int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); select函数可以监听read,write,except的fd。当select返回后,可以遍历对应的fd_set来寻找就绪的fd,从而进行业务处理 select诞生比较早,几乎在所有的平台中都支持。但是select有个缺点就是**单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但是这样也会造成效率的降低。** 除此之外,包含大量fd的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,其开销也随着文件描述符数量增加而线性增大。 poll 函数签名如下所示: 1 2 3 4 5 6 int poll (struct pollfd *fds, unsigned int nfds, int timeout); struct pollfd { int fd; /* file descriptor */ short events; /* requested events to watch */ short revents; /* returned events witnessed */ }; 同select一样,poll返回后,也是需要轮询pollfd来获取就绪的fd。不仅如此,所有的fds也是在内核态和用户态中来回切换,也会影响效率。 ...

March 22, 2026 · 1 min · santu

负载(Load)和CPU利用率之间有什么区别?

典型回答 负载(Load)和 CPU 利用率是衡量系统性能的两个不同的指标,它们从不同的角度反映了系统的状态。 CPU 利用率表示 CPU 正在执行指令的时间比例,即 **CPU 忙碌的程度。**它是一个百分比值,表示在某个时间间隔内,CPU 处于非闲置状态的时间比例。例如,如果 CPU 利用率为 70%,这意味着在观察的时间间隔内,有 70% 的时间 CPU 正在处理任务,而 30% 的时间处于空闲状态。 ✅什么是CPU利用率?怎么算的? 负载(Load)通常指的是一段时间内系统等待处理的工作量。在 Unix-like 系统中,负载平均(Load Average)通常表示在过去 1 分钟、5 分钟和 15 分钟内运行队列的平均长度。运行队列长度是指在某一时刻,处于就绪状态和运行状态的进程数量的和。这个数值包括了正在使用 CPU 的进程和等待 CPU 的进程。 ✅什么是Load(负载)? 所以: CPU 利用率关注的是 CPU 的忙碌程度,而负载关注的是系统中等待运行的工作量。 高 CPU 利用率表示 CPU 正在积极工作,而低 CPU 利用率可能意味着 CPU 大部分时间处于空闲。 高负载意味着有很多进程等待使用 CPU,可能会导致系统响应变慢。 我相信很多人看到这里还是没听懂是吧?那我们举个例子: 想象一家餐厅,这家餐厅有4张餐桌( CPU 的核心数),每张餐桌只能服务一个顾客(任务或者进程)。 如果说,晚高峰时段,4张餐桌中有3张一直有顾客在用餐,那么我们可以说这家餐厅的“使用率”(类似于 CPU 利用率)大概是 75%。这就是CPU利用率。 而“负载”则更像是在描述,除了正在用餐的顾客外,还有多少顾客在等待空出的餐桌。如果晚高峰时段除了3个正在用餐的顾客外,还有1位顾客在等待,我们可以说这个时候餐厅的负载是 4(3位正在用餐 + 1位等待)。如果有4位顾客在用餐,另外4位在等待,那餐厅的负载就是 8。 CPU 利用率是告诉我们餐厅(CPU)的资源(餐桌/处理能力)被使用的程度,而负载则是在告诉我们餐厅面对的顾客总数(包括正在服务的和等待的)。CPU 利用率高,意味着餐厅运转忙碌;负载高,意味着很多顾客需要服务,可能会导致顾客等待。 总结一下就是,CPU 利用率关注的是资源的使用效率,而负载则关注的是服务的压力大小。

March 22, 2026 · 1 min · santu

进程,线程和协程的区别

典型回答 进程是系统进行资源分配和保护的基本单位,线程是处理器调度和分派的基本单位 拿Java程序来说,启动后,每一个JVM其实就是一个进程。所有的资源分配都是基于JVM进程来的。而在这个JVM进程中,又可以创建出很多线程,多个线程之间共享JVM资源,并且多个线程可以并发执行。 进程 进程具有一个独立的执行环境。 进程是程序在计算机上的一次执行活动 。通常情况下,进程拥有一个完整的、私有的基本运行资源集合。特别地,每个进程都有自己的内存空间。 进程往往被看作是程序或应用的代名词,然而,用户看到的一个单独的应用程序实际上可能是一组相互协作的进程集合 线程 线程有时也被称为轻量级的进程。进程和线程都提供了一个执行环境,但创建一个新的线程比创建一个新的进程需要的资源要少。线程是在进程中存在的,每个进程最少有一个线程。线程又如下特点: 线程共享进程的资源,包括内存和打开的文件。线程之间的通信不用进行系统调用,更节约时间 线程更轻量,线程实体包括程序,数据和TCB 线程是调度的基本单位 协程 所谓的协程,是英语翻译过来的(Coroutine),也叫纤程。通过Coroutine来理解,是协作的程序。它其实是不能和进程,线程相提并论的,因为协程是用户态的东西,不会被OS感知到的。但是因为GoLang的大火,大家总是把他们放到一起来比较,所以在这里也一起讲了。 对于多次IO操作来说,我们可以用多线程来完成,但是多线程会引起资源竞争,导致CPU算力的浪费。为了避免这种情况,我们也可以用异步的方式,但是异步的方式会引起callback hell,严重影响了代码的可读性。 所以就需要协程,不让OS通过竞争的方式决定调用哪些线程,而是由用户自己决定如何去执行逻辑。它可以让我们用逻辑流的顺序去写控制流,而且还不会导致操作系统级的线程阻塞。因为协程是由应用程序决定的,所以任务切换的上下文也会交给了用户态来保存。目前GO和Ruby等编程语言都实现了协程,Java也在19的时候引入了协程。可以参考: ✅JDK19 中的虚拟线程是怎么回事? 知识扩展 为什么需要线程?协程? 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。 而在多个进程之间切换的时候,需要进行上下文切换。但是上下文切换势必会耗费一些资源。于是人们考虑,能不能在一个进程中增加一些“子任务”,这样减少上下文切换的成本。比如我们使用Word的时候,它可以同时进行打字、拼写检查、字数统计等,这些子任务之间共用同一个进程资源,但是他们之间的切换不需要进行上下文切换。 所以,在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)。这就是为什么有了进程,又有线程。 但是,多个线程的切换还是需要时间的,而且多线程也会竞争CPU资源引起不必要的资源浪费,更不要说加锁阻塞了。所以,有没有可能不做切换,充分压榨CPU的资源呢?这就诞生了协程。协程可以将用户自己决定什么时候切换,而不是让操作系统去做抢占式调度,这样就大大节约了资源。

March 22, 2026 · 1 min · santu

什么是Load(负载)?

典型回答 负载(load)是Linux机器的一个重要指标,直观了反应了机器当前的状态。 在Linux系统中,系统负载是对当前CPU工作量的度量,被定义为特定时间间隔内运行队列中的平均线程数。load average 表示机器一段时间内的平均load。这个值越低越好。负载过高会导致机器无法处理其他请求及操作,甚至导致死机。 Linux的负载高,主要是由于CPU使用、内存使用、IO消耗三部分构成。任意一项使用过多,都将导致服务器负载的急剧攀升。 扩展知识 查看机器负载 在Linux机器上,有多个命令都可以查看机器的负载信息。其中包括uptime、top、w等。 uptime命令 uptime命令能够打印系统总共运行了多长时间和系统的平均负载。uptime命令可以显示的信息显示依次为:现在时间、系统已经运行了多长时间、目前有多少登陆用户、系统在过去的1分钟、5分钟和15分钟内的平均负载。 1 2 ➜ ~ uptime 13:29 up 23:41, 3 users, load averages: 1.74 1.87 1.97 这行信息的后半部分,显示"load average",它的意思是"系统的平均负荷",里面有三个数字,我们可以从中判断系统负荷是大还是小。 1.74 1.87 1.97 这三个数字的意思分别是1分钟、5分钟、15分钟内系统的平均负荷。我们一般表示为load1、load5、load15。 w命令 w命令的主要功能其实是显示目前登入系统的用户信息。但是与who不同的是,w命令功能更加强大,w命令还可以显示:当前时间,系统启动到现在的时间,登录用户的数目,系统在最近1分钟、5分钟和15分钟的平均负载。然后是每个用户的各项数据,项目显示顺序如下:登录帐号、终端名称、远 程主机名、登录时间、空闲时间、JCPU、PCPU、当前正在运行进程的命令行。 1 2 3 4 5 6 ➜ ~ w 14:08 up 23:41, 3 users, load averages: 1.74 1.87 1.97 USER TTY FROM LOGIN@ IDLE WHAT hollis console - 六14 23:40 - hollis s000 - 六14 20:24 -zsh hollis s001 - 六15 - w 从上面的w命令的结果可以看到,当前系统时间是14:08,系统启动到现在经历了23小时41分钟,共有3个用户登录。系统在近1分钟、5分钟和15分钟的平均负载分别是1.74 1.87 1.97。这和uptime得到的结果相同。 下面还打印了一些登录的用户的各项数据,不详细介绍了。 ...

March 22, 2026 · 2 min · santu

什么是用户态、内核态?如何切换的?

典型回答 在计算机中,内核是操作系统的核心,负责管理和控制计算机硬件资源,提供各种系统服务。假设所有的应用程序都能够直接访问硬件资源,那么可能会导致系统崩溃、数据丢失等问题。 因此,操作系统将应用程序和操作系统内核进行了隔离,确保内核能够独立地控制硬件资源。操作系统内核是运行在特权模式下的,可以访问所有硬件资源和底层系统资源,而应用程序是运行在非特权模式下的,只能访问被授权的资源,不能直接操作硬件资源和底层系统资源。 也就是说,为了保护系统的稳定性和安全性,操作系统将运行在不同的特权模式下,即内核态和用户态。 **内核态是操作系统运行在特权模式下的状态,此时操作系统具有最高的权限,可以访问所有的硬件资源和底层系统资源,如处理器、内存、I/O等。**在内核态下,操作系统可以执行所有的指令,而且不受访问权限的限制。内核态下的程序通常是操作系统内核代码或者设备驱动程序等,它们可以直接访问硬件资源和系统资源,以实现系统的功能和服务。 **用户态是指应用程序运行在非特权模式下的状态,此时应用程序只能访问被授权的资源,不能直接操作硬件资源和底层系统资源。**在用户态下,应用程序只能执行一些受限的指令集,不能直接执行特权指令。当应用程序需要访问系统资源时,需要通过系统调用的方式切换到内核态,请求操作系统提供服务。内核态和用户态之间的切换是通过操作系统内核提供的中断或异常机制实现的。 但是,有的时候,我们的应用进程可能也需要进行一些系统调用,比如读写文件这种IO操作,这时候就会触发用户态向内核态的切换。 此时,CPU会暂停当前进程的执行,保存当前进程的状态(包括程序计数器、寄存器、栈指针等)并切换到内核态执行相应的操作,操作完成后再将控制权切换回用户态,恢复进程的执行。

March 22, 2026 · 1 min · santu

正在持续写入的日志如何清理?

典型回答 如果一个日志正在持续写入,但是它的内容太多了,占用了很大的内存,这时候如果想要清理的话,直接删除是不行的,因为一旦删除这个文件就不存在了,应用会因为找不到日志文件而报错。 那么可以通过以下方式清空文件内容: 1 2 3 4 5 6 7 8 9 > application.log 或者 cat /dev/null > file_name 或者 echo "">file_name

March 22, 2026 · 1 min · santu

进程间通信方式有哪些?

典型回答 进程间通信是指在不同进程之间进行数据交换和信息传递的机制。在操作系统中,有多种方式来实现进程间通信,其中一些常见的方式包括: 管道(Pipe): 管道是一种半双工的通信方式,允许一个进程写入数据到管道,同时另一个进程从管道中读取数据。在Unix/Linux系统中,使用pipe系统调用来创建管道。 ✅什么是全双工和半双工 应用场景:父子进程间通信,例如在shell中执行命令。 命名管道(Named Pipe): 与普通管道不同,命名管道允许不相关的进程通过给定的名称来进行通信。在Unix/Linux系统中,命名管道通过文件系统中的特殊文件实现。 消息队列(Message Queues): 进程可以通过消息队列向其他进程发送消息。消息队列是一种通过消息缓冲区进行通信的机制,进程可以将消息发送到队列,而其他进程则可以从队列中读取消息。在Unix/Linux系统中,使用msgget、msgsnd和msgrcv等系统调用来操作消息队列。 应用场景:进程之间通过消息进行异步通信,特别是在分布式系统中用的比较多,比如我们的MQ消息就是一种分布式系统中多个进程之间通信的方式。 共享内存(Shared Memory): 多个进程可以将同一块内存映射到它们的地址空间中,从而实现共享内存。这样,一个进程对共享内存的写操作会影响到其他进程对相同内存区域的读操作。在Unix/Linux系统中,使用shmget、shmat等系统调用来操作共享内存。 信号量(Semaphores): 信号量是一种用于进程同步和互斥的通信方式。通过信号量,进程可以对资源进行加锁或解锁。在Unix/Linux系统中,可以使用semget、semop等系统调用来操作信号量。 套接字(Socket): 套接字是一种网络编程中常见的通信方式,但也可以用于本地进程间通信。通过套接字,进程可以在不同主机或同一主机上的不同进程之间进行通信。 应用场景:这种就是比较常见的是在网络通信、跨网络进程通信。 文件映射(Memory-mapped Files): 进程可以通过将文件映射到它们的地址空间来共享数据。这种方式通过mmap系统调用在Unix/Linux系统中实现。 这些方式各自有其优缺点,选择合适的IPC方式取决于具体的应用场景和需求。

March 22, 2026 · 1 min · santu

什么是CPU利用率?怎么算的?

典型回答 CPU利用率,又称CPU使用率。顾名思义,CPU利用率是来描述CPU的使用情况的,表明了一段时间内CPU被占用的情况。使用率越高,说明你的机器在这个时间上运行了很多程序,反之较少。使用率的高低与你的CPU强弱有直接关系。 很多人都知道,现在我们用到操作系统,无论是Windows、Linux还是MacOS等其实都是多用户多任务分时操作系统。 使用这些操作系统的用户是可以“同时”干多件事的,这已经是日常习惯了,并没觉得有什么特别。 但是实际上,对于单CPU的计算机来说,在CPU中,同一时间是只能干一件事儿的。 为了看起来像是“同时干多件事”,分时操作系统是把CPU的时间划分成长短基本相同的时间区间,即"时间片",通过操作系统的管理,把这些时间片依次轮流地分配给各个用户使用。 如果某个作业在时间片结束之前,整个任务还没有完成,那么该作业就被暂停下来,放弃CPU,等待下一轮循环再继续做.此时CPU又分配给另一个作业去使用。 由于计算机的处理速度很快,只要时间片的间隔取得适当,那么一个用户作业从用完分配给它的一个时间片到获得下一个CPU时间片,中间有所"停顿",但用户察觉不出来,好像整个系统全由它"独占"似的。 而我们说到的CPU的占用率,一般指的就是对时间片的占用情况。 扩展知识 查看CPU利用率 使用uptime、top、w等命令可以在Linux查看系统的负载情况。其中,top命令也可以用来查看CPU的利用率,除此之外,还可以使用vmstat来查看cpu的利用率。 vmstat命令 vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。 1 2 3 4 ➜ ~ vmstat procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 0 1 0 2446260 0 3202312 0 0 201 16304 1 6 0 0 84 5 1 从上面的结果中我们可以看到很多信息,我们本文重点关注下cpu部分的指标。 1 2 us sy id wa st 0 0 84 5 1 以上几个指标是当前CPU的占用情况。 ...

March 22, 2026 · 3 min · santu

留言给博主