• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

嗨吖呀

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

操作系统

  1. 64位和32位的区别

  • 运行能力不同。64位可以一次性可以处理8个字节的数据量,而32位一次性只可以处理4个字节的数据量,因此64位比32位的运行能力提高了一倍。
  • 内存寻址不同。64位最大寻址空间为2的64次方,理论值直接达到了16TB,而32位的最大寻址空间为2的32次方,为4GB,换而言之,就是说32位系统的处理器最大只支持到4G内存,而64位系统最大支持的内存高达亿位数。
  • 运行软件不同。由于32位和64位CPU的指令集是不同的。所以需要区分32位和64位版本的软件。为了保证兼容性,64位CPU上也能运行老的32位指令。于是实际上我们可以在64位CPU上运行32位程序,但是反过来不行。简而言之就是64位的操作系统可以兼容运行32位的软件,反过来32位系统不可以运行64位的软件。

 

  1. 用户态和内核态

  • linux进程有4GB地址空间,0-3G为用户态地址空间,3-4G是内核态的地址空间,存放整个内核的代码和所有的内核模块以及内核所维护的数据。

  • 特权级的概念

对于任何操作系统来说,创建一个进程是核心功能,创建进程要做很多工作,会消耗很多物理资源,比如分配物理内存,父子进程拷贝信息,拷贝设置页、目录页表等等,这些工作得由特定的进程去做,所以就有了特权级别的概念。最关键的工作必须交给特权级最高的进程去执行,这样可以做到集中管理,减少有限资源的访问和使用冲突。inter x86架构的cpu一共有四个级别,0-3级,0级特权级最高,3级特权级最低。

  • 用户态和内核态的概念

当一个进程在执行用户自己的代码时处于用户运行态(用户态),此时特权级最低,为3级,是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态。Ring3状态不能访问Ring0的地址空间,包括代码和数据;当一个进程因为系统调用陷入内核代码中执行时处于内核运行态(内核态),此时特权级最高,为0级。执行的内核代码会使用当前进程的内核栈,每个进程都有自己的内核栈。

用户运行一个程序,该程序创建的进程开始时运行自己的代码,处于用户态。如果要执行文件操作、网络数据发送等操作必须通过write、send等系统调用,这些系统调用会调用内核的代码。进程会切换到Ring0,然后进入3G-4G中的内核地址空间去执行内核代码来完成相应的操作。内核态的进程执行完后又会切换到Ring3,回到用户态。这样,用户态的程序就不能随意操作内核地址空间,具有一定的安全保护作用。这里说的保护模式是指通过内存页表操作等机制,保证进程间的地址空间不会互相冲突,一个进程的操作不会修改另一个进程地址空间中的数据。

  • 用户态和内核态的切换

当在系统中执行一个程序时,大部分时间是运行在用户态下的,在其需要操作系统帮助完成一些用户态自己没有特权和能力完成的操作时就会切换到内核态。用户态切换到内核态的3种方式:

(1)系统调用

用户态进程主动要求切换到内核态的一种方式。用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作。例如fork()就是执行了一个创建新进程的系统调用。系统调用的机制是使用了操作系统为用户特别开放的一个中断来实现,如Linux的int 80h中断。

(2)异常

当cpu在执行运行在用户态下的程序时,发生了一些没有预知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关进程中,也就是切换到了内核态,如缺页异常。

(3)外围设备的中断

当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令而转到与中断信号对应的处理程序去执行,如果前面执行的指令是用户态下的程序,那么转换的过程自然就会是由用户态到内核态的切换。如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后边的操作等。

这三种方式是系统在运行时由用户态切换到内核态的最主要方式,其中系统调用可以认为是用户进程主动发起的,异常和外围设备中断则是被动的。从触发方式上看,切换方式都不一样,但从最终实际完成由用户态到内核态的切换操作来看,步骤都是一样的,都相当于执行了一个中断响应的过程。系统调用实际上最终是中断机制实现的,而异常和中断的处理机制基本一致。

 

  1. 内部碎片和外部碎片

  • 内部碎片就是已经被分配出去(能明确指出属于哪个进程)却不能被利用的内存空间;
  • 外部碎片指的是还没有被分配出去(不属于任何进程),但由于太小了无法分配给申请内存空间的新进程的内存空闲区域。
  • 单道连续分配只有内部碎片,多道固定连续分配既有内部碎片,又有外部碎片。解决方法:使用伙伴系统算法。

 

  1. 内存规划方式

虚拟内存的由来:当直接让进程使用直接的物理内存时,当对物理内存操作时会出现混乱。有两种方法解决这个问题:一种通过基址寄存器和界线寄存器形成地址空间,通过交换技术解决内存超载,另外一种就是基于分页的虚拟地址技术。

  • 交换技术:把一个进程完整调入内存运行一段时间,然后把他存回磁盘,空闲进程主要存储在磁盘上。缺点:当进程空间大于内存时,不能使用。
  • 虚拟内存:把一个进程的一部分调入内存中运行,当内存没有空闲空间时,将新的覆盖旧的页,同时将旧的写入磁盘。虚拟内存主要使用分页存储管理模式。
  • 分页存储:实际上存储在物理内存上(磁盘上),运行时一页一页读取;
    • 基本思想:用户程序的地址空间被划分成若干固定大小的区域,称为"页",相应地,内存空间分成若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。页面的大小是为2n,通常为1KB、2KB、2n KB等。
    • 优点:页面是主存物理空间中划分出来的等长的固定区域。分页方式的优点是页长固定,便于构造页表、易于管理,且不存在外部碎片。
    • 缺点:页长与程序的逻辑大小不相关。例如,某个时刻一个子程序可能有一部分在主存中,另一部分则在辅存中,这不利于编程时的独立性,并且给换入换出处理、存储保护和存储共享等操作造成麻烦。
  • 分段存储
    • 段是按照程序的自然分界划分的长度可以动态改变的区域。通常程序员把子程序、操作数和常数等不同类型的数据划分到不同的段中,并且每个程序可以有多个相同类型的段。段表本身也是一个段,可以存在辅存中,但一般是驻留在主存中。将用户程序地址空间分成若干个大小不等的段,每段可以定义一组相对完整的逻辑信息。存储分配时,以段为单位,段与段在内存中可以不相邻接,也实现了离散分配。
    • 分段存储方式的优缺点:分页对程序员而言是不可见的,而分段通常对程序员而言是可见的,因而分段为组织程序和数据提供了方便。与页式虚拟存储器相比,段式虚拟存储器有许多优点:
  1. 段的逻辑独立性使其易于编译、管理、修改和保护,也便于多道程序共享。
  2. 段长可以根据需要动态改变,允许自由调度,以便有效利用主存空间。
  3. 方便编程,分段共享,分段保护,动态链接,动态增长
  • 由于段的长度不固定,段式虚拟存储器也有一些缺点:
  1. 主存空间分配比较麻烦。
  2. 容易在段间留下许多碎片,造成存储空间利用率降低。
  3. 由于段长不一定是2的整数次幂,因而不能简单地像分页方式那样用虚拟地址和实存地址的最低若干二进制位作为段内地址,并与段号进行直接拼接,必须用加法操作通过段起址与段内地址的求和运算得到物理地址。因此,段式存储管理比页式存储管理方式需要更多的硬件支持。
  • 段页存储
    • 基本思想:段页式存储组织是分段式和分页式结合的存储组织方法,这样可充分利用分段管理和分页管理的优点。用分段方法来分配和管理虚拟存储器。程序的地址空间按逻辑单位分成基本独立的段,而每一段有自己的段名,再把每段分成固定大小的若干页。用分页方法来分配和管理实存,即把整个主存分成与上述页大小相等的存储块,可装入作业的任何一页。程序对内存的调入或调出是按页进行的,但它又可按段实现共享和保护。
    • 优点
  1. 它提供了大量的虚拟存储空间。
  2. 能有效地利用主存,为组织多道程序运行提供了方便。
  • 缺点:
  1. 增加了硬件成本、系统的复杂性和管理上的开销。
  2. 存在着系统发生抖动的危险。
  3. 存在着内部碎片。
  4. 各种表格要占用主存空间。

段页式存储管理技术对当前的大、中型计算机系统来说,是最通用、最灵活的一种方案。

 

  1. 缺页中断

缺页中断是指令执行过程中产生的中断,而非(一般的中断)在一条指令执行完成后产生的。

 

  1. 页面置换算法

    https://www.cnblogs.com/Leophen/p/11397699.html

进程运行时,若其访问的页面不在内存而需将其调入,但内存已无空闲空间时,就需要从内存中调出一页程序或数据,送入磁盘的对换区,其中选择调出页面的算法就称为页面置换算法。好的页面置换算法应有较低的页面更换频率,也就是说,应将以后不会再访问或者以后较长时间内不会再访问的页面先调出。

  • FIFO(先进先出算法)

FIFO 算法是最简单的页面置换算法。FIFO 页面置换算法为每个页面记录了调到内存的时间,当必须置换页面时会选择最旧的页面。FIFO 算法基于队列实现,FIFO 页面置换算法易于理解和编程。然而,它的性能并不总是十分理想:

  • 其一,所置换的页面可以是很久以前使用过但现已不再使用的初始化模块
  • 其二,所置换的页面可以包含一个被大量使用的变量,它早就初始化了,但仍在不断使用
  • OPT(最佳置换算法)

这种页面置换算法确保对于给定数量的帧会产生最低的可能的缺页错误率。FIFO 和 OPT 算法的区别在于:除了在时间上向后或向前看之外,FIFO 算法使用的是页面调入内存的时间,OPT 算法使用的是页面将来使用的时间。

  • LRU(最近最少使用算法)

选择最近最长时间未访问过的页面予以淘汰,它认为过去一段时间内未访问过的页面,在最近的将来可能也不会被访问。该算法为每个页面设置一个访问字段,来记录页面自上次被访问以来所经历的时间,淘汰页面时选择现有页面中值最大的予以淘汰。

OPT 和 LRU 算法的区别在于:LRU 算法根据各页以前的情况,是"向前看"的,而最佳置换算法则根据各页以后的使用情况,是"向后看"的,LRU 性能较好,但需要寄存器和栈的硬件支持,LRU 是堆栈类的算法,理论上可以证明,堆栈类算法不可能出现缺页异常。

  • Clock(时钟置换算法)

当一个页面被装入内存时,把该位初始化为0,然后如果这个页面被访问(读/写),则把该位置设为1;把各个页面组织成环形链表(类似于钟表面),把指针指向最老的页面(最先进来);

当发生一个缺页中断时,考察指针所指向的最老页面,若它的访问位为0,立即淘汰;若访问位为1,则把该位置为0,然后指针往下移动一格,如此下去,直至找到被淘汰的页面,然后把指针移动到它的下一格。

  • LFU(最不常用算法)

标记不再是0和1,每次调用,标记值+1,缺页时,置换标记值最小的页面

  • MFU(最常使用算法)

 

  1. 进程和线程的区别

进程是资源分配的最小单位,线程是CPU调度的最小单位,一个程序至少一个进程,一个进程至少一个线程。

进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。

线程:是进程的一个执行单元,是进程内调度实体,是比进程更小的独立运行的基本单位,线程也被称为轻量级进程。

  • 为什么会有线程?

  每个进程都有自己的地址空间,即进程空间,在网络或多用户环境下,一个服务器通常需要接收大量不确定数量用户的并发请求,为每一个请求都创建一个进程显然行不通(系统开销大响应用户请求效率低),因此操作系统中线程概念被引进。

  1. 线程的执行过程是线性的,尽管中间会发生中断或者暂停,但是进程所拥有的资源只为线状执行过程服务,一旦发生线程切换,这些资源需要被保护起来。
  2. 进程分为单线程进程和多线程进程,单线程进程宏观来看也是线性执行过程,微观上只有单一的执行过程。多线程进程宏观是线性的,微观上多个执行操作。
  3. 线程的改变只代表CPU的执行过程的改变,而没有发生所拥有的资源的变化。
  • 进程线程的区别:
  1. 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。
  2. 资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,但是进程之间的资源是独立的。
  3. 健壮性:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
  4. 资源消耗:进程上下文切换时,消耗的资源大,效率低。所以涉及到频繁的切换时,使用线程要好于进程。
  5. 共享变量:如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程
  6. 执行过程:每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
  7. 线程是处理器调度的基本单位,进程是资源分配的最小单位。
  8. 两者均可并发执行。
  • 优缺点:
  1. 线程执行开销小,但是不利于资源的管理和保护。线程适合在SMP机器(双CPU系统)上运行。
  2. 进程执行开销大,但是能够很好的进行资源管理和保护。进程可以跨机器迁移。
  • 何时使用多进程,何时使用多线程?
  1. 对资源的管理和保护要求高,不限制开销和效率时,使用多进程。
  2. 要求效率高,频繁切换时,资源的保护管理要求不是很高时,使用多线程。

 

  1. 协程

协程运行在线程之上,当一个协程执行完成后,可以选择主动让出,让另一个协程运行在当前线程之上。协程并没有增加线程数量,只是在线程的基础之上通过分时复用的方式运行多个协程,而且协程的切换在用户态完成,切换的代价比线程从用户态到内核态的代价小很多。

在有大量IO操作业务的情况下,我们采用协程替换线程,可以到达很好的效果,一是降低了系统内存,二是减少了系统切换开销,因此系统的性能也会提升。在协程中尽量不要调用阻塞IO的方法,比如打印,读取文件,Socket接口等,除非改为异步调用的方式,并且协程只有在IO密集型的任务中才会发挥作用。协程只有和异步IO结合起来才能发挥出最大的威力。

 

  1. 分布式锁,进程锁,线程锁

作用范围:分布式锁>进程锁>线程锁

  • 线程锁:主要用来给方法、代码块加锁。当某个方法或者代码块使用锁时,那么在同一时刻至多仅有一个线程在执行该段代码。当有多个线程访问同一对象的加锁方法/代码块时,同一时间只有一个线程在执行,其余线程必须要等待当前线程执行完之后才能执行该代码段。但是,其余线程是可以访问该对象中的非加锁代码块。
  • 进程锁:也是为了控制同一操作系统中多个进程访问一个共享资源,只是因为程序的独立性,各个进程是无法控制其他进程对资源的访问的,但是可以使用本地系统的信号量控制。
  • 分布式锁:当多个进程不在同一个系统之中时,使用分布式锁控制多个进程对资源的访问。

 

  1. 生产者消费者模式

生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。优点:支持并发、解耦。

 

  1. 进程间通信的方式

  • 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系(通常是指父子进程关系)的进程间使用。普通管道允许两个进程按标准的生产者-消费者方式进行通信:生产者向管道的一端(写入端)写,消费者从管道的另一端(读出端)读。因此,普通管道是单向的,只允许单向通信。如果需要双向通信,那么就要采用两个管道,而每个管道向不同方向发送数据。
  • 命名管道(named pipe):匿名管道是根据相同的文件描述符找到对方,而命名管道是根据相同的文件名字。命名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。ps:文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符。
  • 信号( sinal ):信号是一种异步的通信方式,用于通知接收进程某个事件已经发生。一个进程向另一个进程发送信号,系统从用户态进入内核态,内核根据接收进程的id找到其task_struct,把发送的信号放入接收进程队列。若干时刻过后,接收进程运行,运行一段时间后,接收进程需要用到内核服务,所以通过系统调用(异常或者中断)进入内核态,内核首先找到进程的信号队列,进入用户态,处理信号处理程序。处理完之后,再次进入内核态,找到信号处理前的指令,一切恢复正常,就好像没有信号处理一样。信号处理程序和主程序就好像是两个不同线程,共享进程的用户空间,却没有方法同步。信号处理程序不可能中断执行阻塞然后又转到主程序执行。信号处理程序的优先级高,但是指向条件苛刻。
  • 信号量( semophore ):信号量是一个计数器,在访问一段内存的时候查看某一个信号是否可以访问,保证同一时刻只有一个进程访问这段内存,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,信号量主要作为进程间以及同一进程内不同线程之间的同步手段。
  • 共享内存( shared memory ):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC方式,因为它没有数据拷贝的过程,它是针对其他进程间通信方式运行效率低而专门设计的。共享内存可以不涉及内核操作,但是需要同步和通知控制。比如可以用信号来实现通知。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
  • 内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
  • 套接字( socket ):套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同进程及进程间的通信。
  • 消息队列( message queue ):消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

 

  1. 线程之间通信的方法

线程间通信的模型有两种:共享内存和消息传递。

  1. volatile 关键字:基于 volatile 关键字来实现线程间相互通信是使用共享内存的思想,大致意思就是多个线程同时监听一个变量,当这个变量发生变化的时候,线程能够感知并执行相应的业务。
  2. 使用Object类的wait() 和 notify() 方法:wait和 notify必须配合synchronized使用,wait方法释放锁,在线程A发出notify()唤醒通知之后,依然是走完了自己线程的业务之后,线程B才开始执行。
  3. 使用 ReentrantLock 结合 Condition。
  4. 使用JUC工具类 CountDownLatch:基于AQS框架,相当于也是维护了一个线程间共享变量state。
  5. LockSupport实现线程间的阻塞和唤醒:LockSupport 是一种非常灵活的实现线程间阻塞和唤醒的工具,使用它不用关注是等待线程先进行还是唤醒线程先运行,但是得知道线程的名字。

 

  1. 进程上下文切换与和线程上下文切换

  • 进程的切换过程:实质上就是被中断运行进程与待运行进程的上下文切换。从主观上来理解,只分为两步:
  1. 切换新的页表,然后使用新的虚拟地址空间
  2. 切换内核栈,加入新的内容(PCB控制块,资源相关),硬件上下文切换

  • 什么是上下文切换?

上下文切换就是从当前执行任务切换到另一个任务执行的过程。但是,为了确保下次能从正确的位置继续执行,在切换之前,会保存上一个任务的状态。

  • 区别

进程上下文切换与线程上下文切换最主要的区别就是线程的切换虚拟空间内存是相同的(因为都是属于自己的进程),但是,进程切换的虚拟空间内存则是不同的。同时,这两种上下文切换的处理都是通过操作系统内核来完成的。内核的这种切换过程伴随的最显著的性能损耗是将寄存器中的内容切换出。

 

  1. 多个进程能否监听同一个端口号

根据Unix网络编程中的知识可知,服务端监听一个端口过程:

  1. 根据套接字类型(Ipv4,Ipv6等)创建套接字socket
  2. 将套接字bind绑定到具体的网络地址和端口号
  3. 调用listen开始在这个套接字上进行监听。

Unix提供了一个接口setsockopt()可以在bind之前设置套接字选项,其中就包括REUSEADDR这个选项,表明可以多个进程复用bind函数中指定的地址和端口号。由此可知多个应用(进程),包括同一个应用多次,都是可以绑定到同一个端口进行监听的。对应地C++、NET等高级语言也都提供了对应的接口。

 

  1. 系统突然访问变慢,如何排查和解决?

  • 第一步:登录后台服务器/监控平台,查看系统资源是否达到上限,例如:CPU、内存、磁盘、I/O、网络带宽等,如果是这些问题,先将这些问题逐一解决:
    • 如果是CPU的问题,则需要查看一下CPU占比比较高的进程,然后使用jstack命令生成进程的堆栈信息,看是否发生频繁Full GC,如果是的话,还需要看一下内存快照,分析一下内存情况(可以使用java自带的或第三方工具);
    • 如果是磁盘空间满了,及时清理磁盘;
    • 如果是带宽满了,联系网络工程师解决。
  • 第二步:检查应用服务器(Jboss/Tomcat)的线程池配置是否合理,看一下请求的排队现象是否严重,如果严重则需要重新设置合理的线程池。同样,检查一下数据库的连接池设置是否合理,增大连接池设置,同时检查一下是否有慢sql,如果有慢sql,则进行优化(优化方案是查看执行计划,设置合理的索引等)。
  • 第三步:查看访问慢的服务的调用链,查看一下调用链中的每一步响应时间是否合理,如果不合理,则联系相关系统的负责人进行排查和解决。
  • 第四步:检查web服务器的请求日志,看一下是否存在Doss攻击,如果有Doss攻击,则将攻击者的IP添加到防火墙的黑名单里。

 

  1. CPU突然飙升,如何排查?

  • 可能的原因主要有两种:
  1. 代码中某个位置读取数据量较大,导致系统内存耗尽,从而导致Full GC次数过多,系统缓慢;
  2. 代码中有比较耗CPU的操作,导致CPU过高,系统运行缓慢;相对来说,这是出现频率最高的两种线上问题,而且它们会直接导致系统不可用。
  • 有几种情况也会导致某个功能运行缓慢,但是不至于导致系统不可用:
  1. 代码某个位置有阻塞性的操作,导致该功能调用整体比较耗时,但出现是比较随机的;
  2. 某个线程由于某种原因而进入WAITING状态,此时该功能整体不可用,但是无法复现;
  3. 由于锁使用不当,导致多个线程进入死锁状态,从而导致系统整体比较缓慢。

 

  1. 常用Linux命令

详细地址:https://www.runoob.com/w3cnote/linux-common-command-2.html

  1. ls 命令不仅可以查看 linux 文件夹包含的文件,而且可以查看文件权限(包括目录、文件夹、文件权限)查看目录信息等等。
  2. cd 命令切换当前目录至 dirName。
  3. pwd 命令用于查看当前工作目录路径。
  4. rm 命令删除一个目录中的一个或多个文件或目录,如果没有使用 -r 选项,则 rm 不会删除目录。如果使用 rm 来删除文件,通常仍可以将该文件恢复原状。
  5. rmdir 命令从一个目录中删除一个或多个子目录项,删除某目录时也必须具有对其父目录的写权限。注意:不能删除非空目录
  6. mv 命令移动文件或修改文件名,根据第二参数类型(如目录,则移动文件;如为文件则重命令该文件)。当第二个参数为目录时,第一个参数可以是多个以空格分隔的文件或目录,然后移动第一个参数指定的多个文件到第二个参数指定的目录中。
  7. cp 命令将源文件复制至目标文件,或将多个源文件复制至目标目录。注意:命令行复制,如果目标文件已经存在会提示是否覆盖,而在 shell 脚本中,如果不加 -i 参数,则不会提示,而是直接覆盖!
  8. find 命令用于在文件树中查找文件,并作出相应的处理。
  9. chmod 命令用于改变 linux 系统文件或目录的访问权限。
  10. more 命令功能类似于 cat, more 会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会往回(back)一页显示。
  11. less 命令,less 与 more 类似,但使用 less 可以随意浏览文件,而 more 仅能向前移动,却不能向后移动,而且 less 在查看之前不会加载整个文件。
  12. cat 命令主要有三大功能:1)一次显示整个文件: cat filename;2)从键盘创建一个文件: cat > filename;3)将几个文件合并为一个文件: cat file1 file2 > file。
  13. head 命令用来显示档案的开头至标准输出中,默认 head 命令打印其相应文件的开头 10 行。
  14. tail 命令用于显示指定文件末尾内容,不指定文件时,作为输入信息进行处理。常用查看日志文件。
  15. grep 命令强大的文本搜索命令,grep(Global Regular Expression Print) 全局正则表达式搜索。
  16. vim具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性,方便程序设计。缺点:会将文件全部载入内存中

 

  1. Linux如何通过命令查看日志文件的某几行(中间几行或最后几行)

  • cat filename | tail -n +3000 | head -n 1000
    • tail -n 1000:显示最后1000行
    • tail -n +1000:从1000行开始显示,显示1000行以后的
    • head -n 1000:显示前面1000行
    • head -n -10 t.log:显示 t.log最后 10 行

 

  1. I/O调度算法

  2. CFQ(Completely Fair Queuing,完全公平排队)
  • 特点:
    • 在最新的内核版本和发行版中,都选择CFQ做为默认的I/O调度器,对于通用的服务器也是最好的选择。
    • CFQ试图均匀地分布对I/O带宽的访问,避免进程被饿死并实现较低的延迟,是deadline和as调度器的折中。
    • CFQ对于多媒体应用(video,audio)和桌面系统是最好的选择。
    • CFQ赋予I/O请求一个优先级,而I/O优先级请求独立于进程优先级,高优先级进程的读写不能自动地继承高的I/O优先级。
  • 工作原理:

CFQ为每个进程/线程单独创建一个队列来管理该进程所产生的请求,也就是说每个进程一个队列,各队列之间的调度使用时间片来调度,以此来保证每个进程都能被很好的分配到I/O带宽。I/O调度器每次执行一个进程的4次请求。

  1. NOOP(电梯式调度程序)
  • 特点:
    • NOOP实现了一个FIFO队列,它像电梯的工作一样对I/O请求进行组织,当有一个新的请求到来时,它将请求合并到最近的请求之后,以此来保证请求同一介质。
    • NOOP倾向饿死读而利于写。
    • NOOP对于闪存设备,RAM,嵌入式系统是最好的选择。
  • 电梯算法饿死读请求的解释:

因为写请求比读请求更容易。写请求通过文件系统cache,不需要等一次写完成,就可以开始下一次写操作,写请求通过合并,堆积到I/O队列中。读请求需要等到它前面所有的读操作完成,才能进行下一次读操作。在读操作之间有几毫秒时间,而写请求在这之间就到来,饿死了后面的读请求。

  1. Deadline(截止时间调度程序)
  • 特点:
    • 通过时间以及硬盘区域进行分类,这个分类和合并要求类似于noop的调度程序。
    • Deadline确保了在一个截止时间内服务请求,这个截止时间是可调整的,而默认读期限短于写期限。这样就防止了写操作因为不能被读取而饿死的现象。
    • Deadline对数据库环境(ORACLE RAC,MYSQL等)是最好的选择。
  1. AS(预料I/O调度程序)
  • 特点:
    • 本质上与Deadline一样,但在最后一次读操作后,要等待6ms,才能继续进行对其它I/O请求进行调度。
    • 可以从应用程序中预订一个新的读请求,改进读操作的执行,但以一些写操作为代价。
    • 它会在每个6ms中插入新的I/O操作,而会将一些小写入流合并成一个大写入流,用写入延时换取最大的写入吞吐量。
    • AS适合于写入较多的环境,比如文件服务器
    • AS对数据库环境表现很差。

 

  1. Inode

https://blog.csdn.net/Csoap2/article/details/87706737

  • 定义:储存文件元信息的区域就叫做inode,中文译名为"索引节点"。
  • 内容:inode包含文件的元信息,具体来说有以下内容:
    • 文件的字节数
    • 文件拥有者的User ID
    • 文件的Group ID
    • 文件的读、写、执行权限
    • 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
    • 链接数,即有多少文件名指向这个inode
    • 文件数据block的位置

可以用stat命令,查看某个文件的inode信息:stat example.txt。总之,除了文件名以外的所有文件信息,都存在inode之中。至于为什么没有文件名,下文会有详细解释。

 

  1. 临界区,互斥量,信号量和事件之间的区别

四种进程或线程同步互斥的控制方法

  1. 临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
  2. 互斥量:为协调共同对一个共享资源的单独访问而设计的。
  3. 信号量:为控制一个具有有限数量用户资源而设计。
  4. 事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。

 

  1. 套接字阻塞和非阻塞

Windows套接字在阻塞和非阻塞两种模式下执行I/O操作。在阻塞模式下,在I/O操作完成前,执行的操作函数一直等候而不会立即返回,该函数所在的线程会阻塞在这里。相反,在非阻塞模式下,套接字函数会立即返回,而不管I/O是否完成,该函数所在的线程会继续运行。

非阻塞套接字在控制建立的多个连接,在数据的收发量不均,时间不定时,明显具有优势。这种套接字在使用上存在一定难度,但只要排除了这些困难,它在功能上还是非常强大的。通常情况下,可考虑使用套接字的"I/O模型",它有助于应用程序通过异步方式,同时对一个或多个套接字的通信加以管理。

 

 

posted on 2021-08-24 21:03  嗨吖呀  阅读(104)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3