操作系统考研笔记(王道408)

文章目录

  • 前言
  • 计算机系统概述
    • OS的基本概念
    • OS的发展历程
    • OS的运行机制
    • OS体系结构
    • OS引导
    • 虚拟机
  • 进程和线程
    • 进程和线程基础
      • 进程
      • 进程状态
      • 进程控制
      • 进程通信
      • 线程
      • 线程实现
    • CPU调度
      • 调度的层次
      • 进程调度细节
      • 调度算法
        • 评价指标
        • 批处理调度算法
        • 交互式调度方法
    • 同步与互斥
      • 基本概念
      • 互斥
        • 互斥软件实现
        • 互斥硬件实现
        • 互斥锁(自旋锁)
      • 信号量
        • 信号量机制
        • 信号量实现互斥同步
      • 经典信号量问题
        • 生产者消费者——基本的分析思路
        • 多生产者多消费者——多种生产者
        • 吸烟者问题——多功能生产者
        • 哲学家进餐问题——连续申请多个资源
        • 读者写者问题
    • 死锁

前言

学校OS课程的知识和408有一定的重叠,但是还不太够,因此我又一次打开了王道的OS课程。

这个笔记同理,只记最关键的内容和思考,直接针对408,基础性的概念性的知识以视频为主。

计算机系统概述

OS的基本概念

在这里插入图片描述
OS提供的服务:

  1. 用户级别:
    • GUI,就是windows
    • 命令接口
      • 联机:有交互性,即cmd命令行
      • 脱机:批处理,即.bat文件
  2. 程序员级别:
    • 系统调用:OS的api
    • 系统调用可以通过c语言的操作系统库函数调用,但是c语言本质上比系统调用还高一级

在这里插入图片描述
异步的前提是并发,程序之间交叉前进,即走走停停,无法预知。

OS的发展历程

在这里插入图片描述

  1. 手工阶段,缺点:
    • 独占
    • 人太慢,机器速度逐渐加快,人拖累机器
  2. 单通道批处理
    • 优:提升预处理速度,不拖累机器
    • 缺:独占
  3. 多通道批处理
    • 优:解决独占,实现并发,提升效率
    • 缺:无交互能力
  4. 分时系统
    • 优:解决交互能力,用户“看起来”独占
    • 缺:没有优先级
  5. 实时系统
    • 优:解决了优先级响应问题,及时可靠

OS的运行机制

在这里插入图片描述
OS内核相当于OS的管理员,因此特权指令只能是内核执行。

平时用户的特权调用,操作都是向管理员申请,而不是亲力亲为。

两个状态的切换:

  1. 升级:特权指令触发中断(硬件),OS响应中断的时候进入核心态
  2. 降级:OS主动修改PSW让出控制权(软件)
    • 修改PSW的指令,本身就是特权指令

在这里插入图片描述

中断和计组第5章衔接

涉及到进程之间的协调,就一定要OS接入,进而需要系统调用。

在这里插入图片描述

需要注意,陷入指令是用户态指令(请求),接下来才会因为内中断进入核心态(执行)

在这里插入图片描述

OS体系结构

在这里插入图片描述

我们OS学的功能,可以放在内核,也可以放在用户,这就形成了大内核和微内核的区别。

微内核暴露的接口多,易于维护和扩展,但是沟通成本大,要反复调用。

在这里插入图片描述

在这里插入图片描述

  1. 分层结构
    • 类似于计网的层次结构,结构清晰,通病是效率偏低
  2. 模块化
    • 主模块分离,模块之间分离,平等
      • 优点:可以同时开发,且效率不错
      • 缺点:模块间的图关系很难把握
    • 动态可加载模块。
      • 可加载说白了就是插件,有没有都不影响运行,因此可以动态加载,比如驱动
  3. 宏内核和微内核
    • 微内核相当于一个服务器,中转不同模块之间的`消息传递
  4. 外核
    • 外核可以提供一些高级的资源(未经抽象的资源)分配方式
    • 内核分配的资源都是抽象的,虚拟化的,比如虚拟地址,外核可以直接分配物理地址,在一些需要频繁跳跃的场景,外核直接分配一片连续空间效果会很好。当然,外核也负责保证安全。
    • 跳过虚拟步骤,就相当于跳过了映射层,可以提高效率,缺点是复杂。

OS引导

在这里插入图片描述

简单来说,就是开机扫ROM就可以把操作系统拉起来,但是具体还是要分几步走:

  1. 扫ROM,启动BIOS,自检
  2. 读磁盘的MBR,获取分区
  3. 从活动分区(C盘)中读PBR,获取C盘根目录
  4. 通过目录找到操作系统的程序,拉到内存中,完成OS启动

这四步环环相扣,前一个获取了信息,后一步才能根据此信息行动。

而第4步用的程序,位置一般在C:/Windows/Boot/下面。

虚拟机

在这里插入图片描述

  1. 第一类VMM,相当于传统OS的加强版,直接运行在硬件上
    • 虚拟OS看起来像一个OS,也有内核,但是实际上还是用户态,因此一个特权指令实际上要经过一次虚拟的系统调用+一次真正的系统调用。
    • 迁移性差,因为直接和硬件耦合
  2. 第二类VMM,是寄居在宿主OS之上的,分为两部分
    • 用户态的VMM和宿主的应用程序是共存的
    • 核心态的VMM是以驱动的形式存在的,持续运行在内核态

在这里插入图片描述

进程和线程

进程和线程基础

进程

在这里插入图片描述

PCB,记录进程元数据:

  1. 描述信息。用于区分进程,PID,UID
  2. 进程控制和管理信息。和进程运行状态有关
  3. 资源分配清单。
    • 资源是进程外部的,而数据段是程序产生的内部数据
  4. 处理器相关信息。寄存器上下文

进程特征:

  1. 并发性和异步是一起的
  2. 结构性指的是每个进程的结构都一样,都是PCB+数据段+程序段

进程状态

在这里插入图片描述

进程控制

在这里插入图片描述

在这里插入图片描述

创建原语分为4步:

  1. PCB创建和初始化
  2. 分配资源(此时进入就绪态)
  3. 插入就绪队列

撤销是逆过程:

  1. 剥夺所有资源,清理子进程
  2. 删除PCB

在这里插入图片描述

阻塞和唤醒,是可逆的过程

  1. 修改PCB:可逆,所以现场要保护起来
  2. 切换队列:把PCB放到对应队列中

无论是阻塞还是进程切换,都要剥夺CPU,而进程有一些内容还存在寄存器中,这些寄存器上下文就是保护现场要做的工作,是中断隐指令的内容。

在这里插入图片描述

进程通信

在这里插入图片描述

  1. 共享储存
    • 把两个进程的虚拟储存,映射到同一个物理储存区域
    • 因此要互斥访问
  2. 消息传递
    • 每一个进程都有一个消息队列
    • 直接通信:A进程把消息直接挂到B进程消息队列里
    • 间接通信:以信箱为中介,B要主动去信箱取出A发来的消息
  3. 管道通信
    • 联系生产者消费者,管道其实就是一个循环队列,是个内存缓冲区
    • 管道互斥访问,因此是半双工(像水管)

线程

在这里插入图片描述

在这里插入图片描述

  1. TCB:Thread CB
  2. 一个进程内部,线程之间资源共享
    • 因此切换成本很小,其就是为了频繁切换,提高并发性而生的。
  3. 一个程序的多线程可以放到不同进程中
    • 多核CPU的超线程
    • 但是这样就无法共享资源了,各用个的

在这里插入图片描述

线程可以理解为剥离掉公用资源后,剩下的相互独立的部分

因此线程的内容比较少,切换的时候只需要保证TCB里面的一些寄存器上下文就可以,比进程少很多。

线程实现

在这里插入图片描述

在这里插入图片描述

用户级线程,适用于早期OS没有线程管理功能的时候:

  1. 本质上是用户自己用代码(线程库)管理线程的调度
    • 在OS看来,只有一个进程而已
    • 线程的调度是纯用户态行为,这种调度非常简单(线程库的逻辑)
  2. 优缺点
    • 优:不需要系统调用,高效
    • 缺:假线程,代码在一个线程卡住,实际上都卡住了

在这里插入图片描述

内核级线程,这是经典的OS负责的线程:

  1. 优点:真并发
  2. 缺点:核心压力大

因此内核级线程又分出多种模式:

  1. 一对一
    • 这其实和内核级线程一样
  2. 多对一:多个用户级线程对应一个内核线程,而CPU只能看到内核线程
    • 这个模式比较鸡肋,和用户级线程一样
  3. 多对多:多个用户级线程,映射到多个内核线程
    • 这才是真神
    • 可以把用户线程切分成3块,每一块都用多对一模型映射到一个线程,整体上三个部分有序工作,互相之间不会拖累,兼顾了效率和并发性

在这里插入图片描述

CPU调度

调度的层次

在这里插入图片描述

作业调度,作业≈一个程序,储存的位置是外存,作业调度≈程序启动
低级调度,针对进程,切换CPU

中级调度,和作业调度一样都是在内外存之间的,区别如下:

  1. 作业调度是比较彻底,就是启动和终止
  2. 中级调度类似于休眠(挂起),暂时放到外存(手机的扩展内存技术就是这样实现的)
    • 引入7状态模型,对就绪和阻塞分别增加对应的挂起状态
    • 在挂起状态(外存里),也可以实现阻塞到就绪的转变
    • 从运行态可以跳过就绪态,直接跳到挂起

在这里插入图片描述

进程调度细节

在这里插入图片描述
进程调度时机:

  1. 主动
  2. 被动。说白了就是被抢占
    • 中断处理(中断隐指令)和原子操作,都会关中断,因此不会被打断
    • OS内核处理内核临界区的时候,权限高,不可被打断

区分一下:

  1. 狭义进程调度。在CPU空闲的时候,抓一个就绪态进程激活
  2. 进程切换。剥夺一个运行的进程,换成另外一个进程
    • 两个操作都要恢复新现场
    • 相比于调度,切换额外要做的操作是保护旧现场

广义的进程调度,可能包含了进程切换这一过程

在这里插入图片描述

最后提一嘴调度程序,我们说,调度是由OS控制的,本质上就是软件,那么说白了,负责调度的管理者,还是一个程序。

这个程序什么时候会运行呢?

  1. 如果是非抢占的时候,就是异步的运行,在特殊情况才运行(创销,阻塞唤醒)
  2. 抢占式的,那么就要定期巡查,决定一个CPU是否应该抢占

调度算法

评价指标

在这里插入图片描述

  1. 周转时间=等待+处理时间
  2. 带权周转时间
    • 本质上是个比例值,可以衡量等待时间在周转时间中的占比
    • 越大,则等待越久
  3. 等待时间。
    • 执行之前的时间,执行起来后等IO的时间不算
    • 作业的等待时间是在成为进程之前的那段时间
    • 进程的等待时间就是创建态+就绪态的那段时间
  4. 响应时间
    • 和等待时间类似,但是针对的只是一种请求,比如键盘,鼠标
批处理调度算法

在这里插入图片描述

在这里插入图片描述

对于非纯计算程序,IO时间不算等待,因此还要抛去IO操作的部分。

FCFS(其实就是FIFO),之所以对短作业不利,就是因为短作业的带权周转时间会很大,这代表其体验很差。

加粗样式

短=Short,即SJF,SPF

具体计算,要分为三部分:

  1. 还没来的作业
  2. 作业池中的作业
  3. 正在运行的作业

正在运行的作业只能在作业池中挑选,而不能是还没有进入作业池的,因此第一个任务只能是P1,即使他时间很长。

SJF分两种:

  1. 非抢占式的SJF如上
    • 比较简单,顺序操作
    • 只需要在作业完成时,分析作业池即可
  2. 抢占式的SJF(SRTN
    • 如果有一个新的作业来了,那么就有可能比当前正在运行的作业的剩余时间短,此时就把作业替换回作业池中(记得标注剩余时间)
    • 具体做题的时候,比非抢占式要额外多分析新作业来的时间点

在这里插入图片描述

  1. 题目区分细节
    • 默认非抢占,但是比较模糊
    • 考虑到抢占,SRTN的平均周转时间肯定是最少的
    • 如果默认作业没有到达顺序的先后之分,那么非抢占SJF=SRTN
  2. SJF对长作业不利,无论是否抢占,都可能造成饥饿现象

在这里插入图片描述

HRRN用到响应比指标,综合了等待时间和处理时间,在保证了优先级的前提下,修复了SJF饥饿的问题。

分析思路和SJF类似,都是分成三部分,HRRN为非抢占式的,所以只在CPU空闲的时候对作业池进行分析。

注意,其等待时间是从到达开始计数的。

交互式调度方法

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

RR(时间片轮转)

  1. 轮转本身很简单
    • 建立一个就绪队列,每一个时间片出队,处理队头对应的进程
    • 时间片完了以后就插到队尾
  2. 难在新任务来的时候,会改变队列结构
    • 新任务来了,也是插在队尾
    • 如果A任务的时间片完了,此时B任务刚来,这二者的顺序以B为先,毕竟新来的要照顾一下(注意,这个照顾顺序只针对想要同时入队的两个任务,前面早就在队里的任务仍然在前面)
  3. 如果任务处理完,时间片还没用完,会直接终止当前时间片
    • 很正常很人性化的设计,干等着没意思

因此,整个分析过程需要考虑的也是处理完以及新任务刚来的两种时刻。

严格来说,RR不会剥夺正在执行的时间片,但是先来先插到队尾的这种逻辑,以及规定时间片用完就剥夺,这两个操作具有抢占性,所以我们规定RR是抢占式的(剥夺的来源是时间片本身,而不是其他进程)

时间片太大,就会退化为FCFS,太小则切换开销占时间片的比例就太大了(类似于流水线那个感觉),效率降低。

在这里插入图片描述

优先级调度算法。优先数越高,就越排在前面激活。

此方法分为抢占式和非抢占式。
分析节点参考SJF。

在这里插入图片描述

多级反馈队列调度,这个是666,真神

我们直接分析一下其性质,相当复杂,但是又相当合理:

  1. 队列内部是RR,队列之间是抢占
  2. 关于优先级
    • 新手保护:刚来的,优先级最高
    • 耗时降级:如果耗时长,每完整执行一个时间片,优先级就会降低一级,直到降无可降
    • 被剥夺不降级:被剥夺严格来说不算执行完一个时间片,因此不降级,只是按RR原则放到了队尾。不过还会有补偿,新获得的时间片又是一个完整的时间片
  3. 关于轮转
    • 优先高级:高一级的队列为空,才对下一级进行RR遍历(有抢占性,如果高一级来了新的,则立马切到高一级)
    • 保障低级:越低级,时间片越长。虽然低优先级低人一等,但是总得让人家执行完,所以低优先级的时间片反而会更多,一旦轮到了,就可以持续执行很长时间(当然,如果你不争气,执行不完那就继续降级,又或者被强占,总之还是低人一等)

优缺点分析:

  1. 公平:FCFS
  2. 快响应:RR+优先级调度
  3. 短进程优先:SPF
  4. 自动优先级
    • 如果想要保证任务的高优先级,可以尽量让其不降级,比如如果进程因为IO主动放弃时间片,此时我们不认为其执行完毕,因此不降级,这样就保证了IO的高优先级
  5. 缺点:仍然不是绝对公平,因此会造成饥饿

在具体实践中,为了防止饥饿出现,可能一个队列会分配固定的时间上限,如果超过这个界限,还是要切换队列的,不能一直卡在高优先级队列。
此外,不同队列内部的策略还可以不一样。

在这里插入图片描述

同步与互斥

基本概念

在这里插入图片描述

异步就是无序性
同步就是有序性,A一定在B前。

遵循的原则,总结起来就是,忙可以先等一下,等久了就撤(让权),但是你不能让我等太久,过一段时间我还得拿回权利并且进入临界区。

互斥

互斥软件实现

在这里插入图片描述
在这里插入图片描述

单标志法是最原始的轮询

本质上,turn代表谦让以及指定,刚开始就指定一个进程,而一个进程执行完以后又会指定另外一个进程。
但是其问题在于,临界区使用权和CPU占用权是分裂的,让给你用,并不代表你就能用,即空闲也进不去,违背“空闲让进”

比如此时标记0进程能用临界区,但是此时CPU时间片属于1,此时while循环就会持续1个时间片,一边是忙等,另一边是空闲没人用

在这里插入图片描述

双标志法,把谦让逻辑变成了,将指定变成了排他逻辑,占用逻辑。

占用和释放,只修改自己的占用标记,不去指定他人。

双标志先检查,检查和上锁不连贯,此时,按照1526顺序,A还没上锁,B就通过检查了,就会同时进入临界区,即“忙”也能进去,违反了忙则等待。

为了修正,出现了双标志后检查法,这种方法先把临界区标记了,再检查,那么就可以确保别人拿不到临界区(缺德做法),但是这很明显不靠谱,会出现都用不上的情况,按照1526顺序,AB都标记,则会排他,那么AB就都会卡在检查阶段。

此时,即使临界区空闲,AB谁也不让着谁,谁也用不上,这违背了“空闲让进”,而且一直卡死,违背了“有限等待”

在这里插入图片描述

在这里插入图片描述

peterson算法,综合了单标志和双标志后检查法

标志代表意愿,turn代表谦让,最后被谦让的那一个,就可以获得使用权。

以1627举例,2先谦让一下,但是7后面有谦让一下,于是2就勉为其难的进入了,和现实的套路一模一样。
本质上,turn同一时间有且只能有一个值,因此同一时间只能有一个进程跳出循环,且必有一个进程跳出循环。

非常牛逼的思路,但是仍然优缺点,因为进程仍然是忙等状态,即违反了“让权等待”,但是已经是成本最低的了,这个操作可以通过时间片轮转来剥夺。

互斥硬件实现

在这里插入图片描述
关中断的缺点:

  1. 多处理机,关不了其他CPU,进程可以借助其他CPU访问临界
  2. 仅内核。因为这个操作给用户太危险

在这里插入图片描述

TestSet的操作,说白了就是用old检查,并对lock进行上锁,这是一个原子过程,检查和上锁是一气呵成的。
如果lock原来就是true,那么再上也无所谓
如果lock原来是false,那么就可以同时实现上锁+退出循环,不用担心被打断

上面这个代码只是模拟,实际上是硬件TSL指令实现的,是原子的,而软件编程是无法达到这个效果的。
缺点和peterson一样,都是忙等,不满足“让权等待”原则

还有一个Swap指令(Exchange,XCHG指令),和TSL基本一样的逻辑和特性

互斥锁(自旋锁)

互斥锁是一种思想,和mutex操作很像,就是申请和释放。

但是其申请过程是忙等的,所以TSL,swap指令都是自旋锁,单标指法其实也是自旋锁,申请过程都具有原子性

当然,正如单标志法哪里说的,忙等其实不完全忙等,时间片没了就退出(单处理器没有RR,所以就是彻底忙等)。甚至说有时候反而有意外效果,等待的时候不用切换上下文,有时候成本反而低。

在这里插入图片描述

信号量

信号量机制

在这里插入图片描述

整形信号量,说白了就是双标志先检查,但是P和V是原语,可以保证不会同时进入

但是因为底层还是一个循环,仍然会忙等,不满足让权等待。

在这里插入图片描述

记录型信号量引入阻塞队列,解决了忙等现象

  1. 原来是忙等,现在发现资源不够就丢到阻塞队列里。
    • 极限情况为0,-1后为负,此时是第一个进程阻塞
  2. 如果资源够了,且阻塞队列里有进程,就唤醒
    • 极限情况为-1,+1后为0,此时把阻塞队列里最后一个进程唤醒
信号量实现互斥同步

在这里插入图片描述

semaphore mutex = 1 :代表记录型信号量,有等待队列

互斥比较简单,mutex=1,PV夹住临界区。

在这里插入图片描述

同步是前V后P,用一个信号量关联两个进程,等V操作执行完后,P才能执行下去。

给定一个拓扑图,只需要把每一个前驱后继关系都用一个信号量定义一下即可。
之后每一个节点都是一个进程,把边定义的前驱后继关系写到进程里面即可:

  1. 入边写P
  2. 出边写V

在这里插入图片描述

经典信号量问题

生产者消费者——基本的分析思路

在这里插入图片描述

需要注意一个细节就是,P操作是不可互换的,因为mutex只夹临界区,夹得多了就会出问题(死锁)
V操作可以互换,因为V操作一定不会被卡住

在这里插入图片描述

多生产者多消费者——多种生产者

在这里插入图片描述

首先是最简单的两组关系:

  1. apple和orange各自有一对同步关系
  2. plate关系:关键在于盘子,盘子是双方的一个中介,并不能单看父或者母,要把父母统一为一方,把子女统一为另一方
    在这里插入图片描述

具体实现如下,三个同步信号量,这里将plate设置为“还可以放的空间”,因此初值为1

因此,整体就实现了一个PV结构,每一个进程,都是有P有V。
mutex实际上可有可无,因为我们这里的资源上限为1,已经相当于mutex的作用了,但是如果盘子空间变成2,就得加mutex了,否则就可能发生覆盖现象。

在这里插入图片描述

如果反过来呢,plate=盘中可用水果数量,会出问题,比如dad,此时就是V(apple),V(plate),可以看到这个进程是没有P的,也就是说不会被阻塞,他可以一直释放。

所以我们这里还可以总结出一条生产者消费者问题中,隐性的要求,就是PV一定是要成环的,相互制约,一个进程只有V无P,必然是有问题的,在我们制定信号量意义的时候,也应该考虑构造一个PV环结构。

吸烟者问题——多功能生产者

在这里插入图片描述

一个多功能生产者,给多个单功能消费者提供原料,同步关系如下

在这里插入图片描述

再拓展一下思路,如果finish定义为1呢?

那么就要把生产者的P操作放在最开始,消费者是不变的,仍然可以正常运行(因为仍然是PV环,而且PV关系没有变)

分析一下是否需要mutex,因为只有一个生产者,所以缓冲区最多有1个元素,不会出问题。
但是呢,如果有n生产者,此时因为生产者是V在前的,第一次生产不受阻塞,所以就可能会让缓冲区里存在n个元素,所以这种写法其实不好,如果是按照我那个P在前的写法,即使是有多个生产者进程,只要规定finish=1,就只能有一个元素被生产

哲学家进餐问题——连续申请多个资源

这个问题本身不难,难在如何解决死锁。

哲学家进餐问题的死锁情况为,每个哲学家都只P了一半,都卡在了第二个P上。
本质上,哲学家进餐是连续申请多个资源,如果申请的途中被卡了,而且是集体卡顿,那就死锁了。

所以解决哲学家死锁,就要从这些领域入手:

  1. 最多让n-1个哲学家同时进餐,这样就一定可以保证有1个哲学家不会被卡死
    • 可以用一个值为n-1的信号量限制
  2. 限定哲学家拿资源的顺序,强制哲学家进行两两竞争
    • 比如指定奇数哲学家先左边的,偶数先拿右边的,那么这一对哲学家必然是两个必有一个阻塞,而另一个没被阻塞的哲学家,在另一边不存在竞争,一定可以吃到
  3. 保证哲学家多个P操作的原子性
    • 在一连串P外面加个mutex即可
    • 即使一个哲学家被卡,其他哲学家也不可能是P操作被卡,即其他哲学家在吃饭,这是暂时的,可以恢复的

在这里插入图片描述

读者写者问题

死锁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/210895.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Plantuml之类图语法介绍(十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

STM32基于USB串口通信应用开发

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进, 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!…

对无向图进行邻接矩阵的转化,并且利用DFS(深度优先)和BFS(广度优先)算法进行遍历输出, 在邻接矩阵存储结构上,完成最小生成树的操作。

一 实验目的 1.掌握图的相关概念。 2.掌握用邻接矩阵和邻接表的方法描述图的存储结构。 3.掌握图的深度优先搜索和广度优先搜索遍历的方法及其计算机的实现。 4.理解最小生成树的有关算法 二 实验内容及要求 实验内容&#…

模电·放大电路的分析方法——图解法

放大电路的分析方法——图解法 静态工作点的分析电压放大倍数的分析波形非线性失真的分析直流负载线与交流负载线图解法的适用范围 在实际测出放大管的输入特性、输出特性和已知放大电路中其它各元件参数的情况下,利用作图的方法对放大电路进行分析即为图解法。 静…

postgresql自带指令命令系列三

目录 简介 bin目录 28.pg_verifybackup 29.pg_waldump 30.postgres 31.postmaster -> postgres 32.psql 33.reindexdb 34.vacuumdb 35.vacuumlo 总结: 简介 在安装postgresql数据库的时候会需要设置一个关于postgresql数据库的PATH变量 export PATH/…

Linux CentOS 7.6安装jdk1.8教程

安装教程 第一种方式(通过yum安装):第一步:输入查找命令:第二步:输入安装命令:第三步:安装完成,输入安装命令后,等到出现Complete!代表安装完成第…

PyTorch实现逻辑回归

最终效果 先看下最终效果: 这里用一条直线把二维平面上不同的点分开。 生成随机数据 #创建训练数据 x torch.rand(10,1)*10 #shape(10,1) y 2*x (5 torch.randn(10,1))#构建线性回归参数 w torch.randn((1))#随机初始化w,要用到自动梯度求导 b …

小米手机锁屏时间设置为永不休眠_手机不息屏_保持亮屏

环境:打开手机自带的锁屏时间设置发现没有 永不息屏的选项 原因:采用了三星OLED屏幕,所以根据OLED屏幕特性,这个是为了防止烧屏而特意设计的。非OLED机型支持设置“永不” 解决方案1:原生系统是支持永不锁屏的&#…

ES 如何将国际标准时间格式进行格式化与调整时区

需求,日志收集的时候,时间格式是国际标准时间格式。形如yyyy-MM-ddTHH:mm:ss.SSS。 (2023-12-05T02:45:50.282Z)这个时区也不对,那如何将此类型的时间,进行格式化呢? 本篇文章体统一个案例&…

Other -- ChatGPT 原理

本文为个人理解,帮助小白(本人就是)了解正在创建新时代的 AI 产品,如文中理解有误欢迎留言。 [参考链接--](https://baijiahao.baidu.com/s?id1765556782543603120&wfrspider&forpc) 1. 了解一些基本概念 大语言模型&a…

【面试】测试/测开(ING)

63. APP端特有的测试 参考:APP专项测试、APP应用测试 crash和anr的区别 1)网络测试 2)中断测试 3)安装、卸载测试 4)兼容测试 5)性能测试(耗电量、流量、内存、服务器端) 6&#xf…

画对比折线图【Python】

出这一期想必是我做某个课程作业遇到了。 由于去各个官网下载对比图要钱,我还是不想花钱的!真讨厌!浅浅水一期。 以下是要做的对比图的数据: 代码: from matplotlib import pyplot as plt#设置中文显示plt.rcParams[…

CSS新手入门笔记整理:CSS浮动布局

文档流概述 正常文档流 “文档流”指元素在页面中出现的先后顺序。正常文档流,又称为“普通文档流”或“普通流”,也就是W3C标准所说的“normal flow”。正常文档流,将一个页面从上到下分为一行一行,其中块元素独占一行&#xf…

ChatGPT OpenAI API请求限制 尝试解决

1. OpenAI API请求限制 Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for gpt-3.5-turbo-16k in organization org-U7I2eKpAo6xA7RUa2Nq307ae on reques…

让内存无处可逃:智能指针[C++11]

智能指针 文章目录 智能指针前言RAII什么是智能指针智能指针的应用示例 C98的auto_ptr共享型智能指针:shared_ptrshared_ptr的使用初始化获取原生指针指定删除器默认删除器default_delete指定删除器指定删除器管理动态数组 shared_ptr的伪实现shared_ptr的注意事项避…

【Docker】进阶之路:(五)Docker引擎

【Docker】进阶之路:(五)Docker引擎 Docker引擎简介Docker引擎的组件构成runccontainerd Docker引擎简介 Docker引擎是用来运行和管理容器的核心部分。Docker首次发布时,Docker 引擎由LXC 和 Docker daemon 两个核心组件构成。 …

linux驱动开发——内核调试技术

目录 一、前言 二、内核调试方法 2.1 内核调试概述 2.2 学会分析内核源程序 2.3调试方法介绍 三、内核打印函数 3.1内核镜像解压前的串口输出函数 3.2 内核镜像解压后的串口输出函数 3.3 内核打印函数 四、获取内核信息 4.1系统请求键 4.2 通过/proc 接口 4.3 通过…

算法:有效的括号(入栈出栈)

时间复杂度 O(n) 空间复杂度 O(n∣Σ∣),其中 Σ 表示字符集,本题中字符串只包含 6 种括号 /*** param {string} s* return {boolean}*/ var isValid function(s) {const map {"(":")","{":"}","["…

python格式化内容

1.字符串格式化: 定义列表 [{"姓名": "张三", "年龄": 18, "性别": "男"}, {"姓名": "里斯李四李斯", "年龄": 18, "性别": "男"}, {"姓名": "斯托夫斯基…

上位机与PLC:ModbusTCP通讯之数据类型转换

前请提要: 从PLC读取的数值,不管是读正负整数还是正负浮点数,读取过来后都会变成UInt16,也就是Ushort类型 一、ushort(UInt16)转成 Int32 源代码方法: //ushort类型转Int32类型的方法private int ushortToInt32(ushort[] date, int start){//先进行判断,长度是否正确…