后端学习 - 操作系统

文章目录

  • 一 基本概念
    • 1 操作系统的特征
    • 2 操作系统的位置
    • 3 计算机的硬件组成
    • 4 中断与异常
    • 5 系统调用
  • 二 进程管理
    • 1 进程控制块 PCB(Process Control Block)
    • 2 进程的状态与转换
    • 3 进程间的通信
    • 4 线程
    • 5 调度算法
    • 6 死锁
    • 7 PV 操作
  • 三 内存管理
    • 1 内存的非连续分配
    • 2 虚拟内存的概念
    • 3 虚拟内存的实现——局部性原理
    • 4 虚拟内存的页面置换算法
    • 5 抖动和颠簸
  • 四 文件管理
  • 五 I/O管理
    • 1 同步与异步
    • 2 阻塞与非阻塞
    • 3 I/O模型:同步阻塞I/O & 同步非阻塞I/O
    • 4 I/O模型:I/O多路复用

一 基本概念

1 操作系统的特征

  • 并发:两个或多个事件,在同一时间间隔内发生
  • 共享:系统中的资源可供内存中多个并发执行的进程共同使用,分为互斥共享方式 / 同时访问方式
  • 虚拟:将一个物理上的实体变为若干逻辑上的对应物
  • 异步:进程的执行不是一贯到底,而是以不可预知的速度向前推进

2 操作系统的位置

  • 操作系统是在硬件的基础之上安装的 软件,能够根据用户输入的指令达到 控制硬件 的效果
  • 操作系统相当于是一个中间层,为用户层和硬件提供各自的接口,屏蔽了不同应用和硬件之间的差异,达到统一标准的作用
  • 大部分计算机有两种运行模式:内核态用户态
  • 软件中最基础的部分是操作系统,它运行在 内核态,操作系统具有硬件的访问权,可以执行机器能够运行的任何指令;软件的其余部分运行在 用户态
    在这里插入图片描述

3 计算机的硬件组成

  • 冯诺伊曼体系结构:运算器、控制器、存储器(内存与外存)、输入设备、输出设备
  • 总线(Buses):总线在组件之间来回传输字节信息。通常总线被设计成传送定长的字节块,也就是 字(word)。字中的字节数是一个基本的系统参数,常见的有 4 个字节(32 位)或者 8 个字节(64 位)
    在这里插入图片描述

4 中断与异常

  • 操作系统内核工作在核心态,用户程序工作在用户态,但用户程序需要使用核心态的功能。中断和异常实现了从用户态到核心态的切换,是用户态转为核心态的唯一途径。发生中断或异常时,运行在用户态的 CPU 会立刻切换成核心态
  • 中断的定义:也称外中断,指来自 CPU 指令以外的事件发生(I/O结束中断、时钟中断等),该类中断通常是与当前指令无关的事件,即它们与当前处理机运行的程序无关
  • 异常的定义:也称内中断或 陷入(trap),指源自 CPU 执行指令内部的事件(程序的非法操作码、地址越界、算术溢出等),对异常的处理一般要依赖于当前程序的运行现场
    在这里插入图片描述

5 系统调用

  • 用户在程序中调用操作系统提供的一些子功能
  • 凡是与资源有关的操作,都必须通过系统调用的方式向操作系统提出服务请求,并由操作系统的内核程序代为完成
  • 发起系统调用需要用户程序执行陷入(trap)指令(该指令不是特权命令,因为是在用户态使用),即通过异常的方式切换为核心态
  • 从核心态转为用户态需要执行中断返回指令,该指令是特权指令
    在这里插入图片描述
  • 和网络模型的对应关系:系统调用发生在5->4时
    在这里插入图片描述

二 进程管理

在这里插入图片描述

1 进程控制块 PCB(Process Control Block)

  • 程序段 + 相关数据段 + PCB = 进程实体;PCB 是一种数据结构,是标志进程存在的唯一标志
  • 创建进程,实际上指创建进程实体中的 PCB;撤销进程,实际上指撤销 PCB
  • PCB 是有限的,如果创建进程时申请 PCB 失败,则创建失败
    在这里插入图片描述

2 进程的状态与转换

状态含义
创建进程正在被创建,尚未转到就绪态
就绪进程获得了除了处理机之外的一切所需资源,一旦得到处理机就可以运行。通常处于就绪态的进程组成就绪队列
运行进程正在处理机上运行
阻塞进程正在等待某一事件而暂停运行,如等待某些资源(不包括处理机)或等待I/O完成等,即使处理机空闲也不能运行
结束进程正在从系统中消失,进程先进入结束态,然后回收释放资源

在这里插入图片描述

  • 从运行态变为阻塞态是主动行为,从阻塞态变为就绪态是被动行为(需要其它进程协助)
  • 进程在切换时,运行信息存放在 PCB 中

3 进程间的通信

  • 共享存储:进程间存在一块可直接访问的共享的空间
    在这里插入图片描述

  • 消息传递:进程间的数据交换以格式化的消息为单位
    在这里插入图片描述

  • 管道通信:消息传递的一种特殊方式,管道指 pipe 文件,连接一个读进程和一个写进程
    在这里插入图片描述

4 线程

  • 线程是轻量级的进程,是最基本的 CPU 执行单元
  • 除了少量的运行必备的资源,线程几乎不拥有系统资源,但可以和同属一个进程的其它线程共享进程拥有的资源
  • 为什么引入线程可以提高系统的并发性:同一进程内的线程相互切换的开销很小,不进行进程的切换;即使线程切换时需要发生进程切换,总体而言进程切换的次数变少了

5 调度算法

  • 衡量调度的一些基本指标:
    周转时间:从作业提交到完成经历的时间
    带权周转时间:作业周转时间和作业实际运行时间的比值
  1. 先来先服务(FCFS)调度算法
    对长作业有利,短作业不利
    在这里插入图片描述

  2. 短作业优先(SJF)调度算法
    对短作业有利,长作业不利
    在这里插入图片描述

  3. 优先级调度算法
    为作业分配优先级,每次选择优先级最高的一个或几个作业执行
    可以分为 剥夺式 / 非剥夺式,静态优先级 / 动态优先级

  4. 高响应比优先调度算法
    响应比 = (等待时间+要求服务时间) / 要求服务时间
    是对 FCFS 和 SJF 的综合平衡,每次选择相应比最高的作业投入运行

  5. 时间片轮转调度算法
    时间片的大小对系统性能影响很大:时间片足够大时,退化成先来先服务;时间片太小时,进程切换过于频繁,CPU 利用率降低

  6. 多级反馈队列调度算法*
    是对优先级调度算法和时间片轮转调度算法的综合
    优先级越高的队列,时间片越小
    高优先级队列可以抢占低优先级队列的 CPU,只有在高优先级队列为空时,CPU 才分配给低优先级队列的进程

每隔一段时间,将所有的进程重置到最高优先级的队列中,防止低优先级的进程饥饿,以及进程类型变化导致的不公平对待
相同优先级的进程轮转运行

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

6 死锁

  • 产生的必要条件
条件解释
互斥条件在某段时间内,资源仅被一个进程占有,其它进程请求该资源只能等待
不剥夺条件进程获得的资源只能主动释放,不能被其它进程强行夺走
请求并保持条件进程已经持有至少一个资源,再请求新的资源时,对已持有的资源保持不放
循环等待条件存在进程资源的循环等待链
  • 处理死锁的策略
    在这里插入图片描述
  1. 死锁预防:破坏产生死锁的产生条件之一
  2. 死锁避免:银行家算法
    进程运行前,先声明对各种资源的最大需求量
    操作系统先测试该进程已占用的资源数与本次申请的资源数是否超过声明的最大需求量,如果超出则拒绝分配
    如果不超出则测试 系统现存的资源能否满足进程需要的最大资源,如果满足则可以分配,否则推迟分配
  3. 死锁检测和解除:资源剥夺、撤销进程、进程回退

7 PV 操作

  • PV 操作是一种实现进程互斥和同步的方法
    P(S):使 S=S-1 ,若 S>=0 ,则该进程继续执行,否则排入等待队列
    V(S):使 S=S+1 ,若 S>0 ,唤醒等待队列中的一个进程
  • 信号量根据作用可以分为 互斥信号量同步信号量
  • 实现互斥的 P 操作一定要放在实现同步的 P 操作之后(先获取资源再获取锁),否则可能会造成死锁;V 操作的顺序可以交换
  1. 生产者-消费者问题
semaphore mutex = 1;  //互斥信号量
semaphore empty = n;  //同步信号量,空闲缓冲区的数量
semaphore full = 0;   //同步信号量,非空缓冲区的数量
producer(){while(1){生成一个产品;P(empty); //消耗一个空闲缓冲区P(mutex);把产品放入缓冲区;V(mutex);V(full)   //增加一个产品}
}
consumer(){while(1){P(full);   //消耗一个产品P(mutex);从缓冲区取出一个产品;V(mutex);V(empty);  //增加一个空闲缓冲区使用产品;}
}
  1. 吃水果问题
  • 桌上有一个盘子,每次能放 n 个水果,妈妈向盘中放苹果,爸爸向盘中放橘子,儿子专等吃盘里的橘子,女儿专等吃盘里的苹果。只要盘子空,妈妈可向盘中放水果,仅当盘中有自己需要的水果时,儿子或女儿可从中取出
  • 因为爸爸和妈妈向盘中放水果需要消耗同一个信号量 empty,所以要加互斥锁
  • 如果仅有一个儿子和一个女儿,在吃水果的时候不需要加互斥锁(消耗的不是同一种水果);如果是多个则需要加
  • 加不加互斥锁,取决于需要进行 P 操作的资源是否存在竞争
mutex = 1  // 互斥量
empty = n  // 同步量
apple = 0  // 同步量
orange = 0  // 同步量mother(){while(1){P(empty);P(mutex);放苹果;V(mutex);V(apple);}
}
father(){while(1){P(empty);P(mutex);放橘子;V(mutex);V(orange);}
}
son(){while(1){P(orange);// P(mutex);吃橘子;// V(mutex);V(empty);}
}
daughter(){while(1){P(apple);// P(mutex);吃苹果;// V(mutex);V(empty);}
}
  1. 抽烟者问题
semaphore offer1=0;  // 为第一个吸烟者提供卷纸和火柴
semaphore offer2=0;  // 为第二个吸烟者提供火柴和烟草
semaphore offer3=0;  // 为第三个吸烟者提供卷纸和烟草
semaphore finish=1;  // 通知供应者继续提供材料provider(){int rand;while(1){P(finish);rand = getRandom()%3;if(rand == 0)V(offer1);else if(rand == 1)V(offer2);elseV(offer3);}
}somker1(){while(1){P(offer1);制作香烟并吸掉;V(finish);}
}
somker2(){while(1){P(offer2);制作香烟并吸掉;V(finish);}
}
somker3(){while(1){P(offer3);制作香烟并吸掉;V(finish);}
}

三 内存管理

在这里插入图片描述

1 内存的非连续分配

非连续分类允许一个程序分散地装入不相邻的内存分区,但需要额外的空间存放索引,导致非连续分配的存储密度低于连续分配。非连续分配管理方式可以根据 分区的大小是否固定,分为分页存储管理方式和分段存储管理方式

  1. 分页存储管理方式
  • 将内存空间划分为大小相等且固定的页(页相对于固定分区分配的划分更小),以页作为内存的基本单位;这种思想类似于固定分区分配,但产生的内部碎片(页内碎片)要小得多
  • 使用页表完成逻辑地址到物理地址的映射,页的逻辑地址 = 页号 + 页内偏移量(也可以只给出总偏移量,通过除法和求余得到页号、页内偏移量)
  • 通过快表(TLB)作为缓存的方式解决了每次访问内存时都需要进行逻辑地址到物理地址的转换,转换速度需要足够快的问题;通过多级页表的方式解决了 页表不能太大,否则利用率会降低的问题(但多级页表会增加查询时间)
分页可能产生少量的内部碎片
对于每个页都需要在页表中记录虚拟地址到物理地址的映射,无论该页是否有数据
  1. 分段存储管理方式
  • 使用段表完成逻辑地址到物理地址的映射,段的逻辑地址 = 段号 + 偏移量
  • 和分页存储相比,段的大小是不固定的。因此不能通过只给出偏移量,通过整数除法得到段号,或通过求余得到段内偏移,即 分段管理的地址空间是二维的
分段的问题是内存空间被划分为不规整的部分,容易出现外部碎片问题
需要基址寄存器和界限寄存器记录内存的起始位置和长度
  1. 段页式管理方式
  • 作业的地址空间首先被划分为若干逻辑段,每段再划分为大小相等的页
  • 逻辑地址 = 段号 + 页号 + 页内偏移量
每个段维护一个页表(避免了纯分页导致的问题:未分配的页都出现在页表里)
段的基址寄存器和界限寄存器记录页表的起始位置和长度

2 虚拟内存的概念

在这里插入图片描述

  • 虚拟内存的实现基于非连续分配的内存管理方式
  • 虚拟内存让每个程序都认为自己“独占内存”,无需考虑覆盖其它程序内存的情况,同时每个程序的内存(虚拟内存)都对应一个很大的字节数组
  • 每个程序的虚拟内存由两部分空间组成:给这个程序分配的 内存空间,以及分配的 磁盘空间
  • 请求的页在内存中命中时可以直接使用;不命中时通过页面置换算法,将请求页从硬盘空间换入内存空间
  • 操作系统完成由虚拟内存地址到 真实内存地址 或者 磁盘地址 之间的映射工作

3 虚拟内存的实现——局部性原理

  • 局部性原理:空间局部性、时间局部性
  • 虚拟内存基于局部性原理实现:程序装入内存时,将程序的一部分装入内存即可启动程序。程序执行时访问到不在内存中的信息,则操作系统将所需要的部分调入内存,然后执行程序;同样地,将暂时不使用的内容换出到外存。这样用户就能获得比实际内存更大的内存体验,可以运行所需内存大于物理内存的程序

4 虚拟内存的页面置换算法

用于决定虚拟内存 换出 哪页,即内存满但是需要调入新页时,决定从 内存 中调出哪一页到 磁盘的对换区

  1. 最佳置换算法
    选择被淘汰的页面是以后永不使用的页面,或是最长时间内不再被访问的对象
    无法实现,但可以用于评价其它算法
  2. 先进先出(FIFO)页面置换算法
  3. 最近最久未使用(LRU)置换算法
    为每个页面设置一个访问字段,记录页面上次被访问以来经历的时间,每次淘汰经过时间最久的页面
  4. 时钟置换算法(CLOCK)
    简单的 CLOCK 算法仅使用 1 位标志当前页的状态,一种改进做法是引入另外的位标志该页是否是脏页,从而延迟替换脏页的内容(因为替换脏页需要将数据写入外存,代价比较大)

5 抖动和颠簸

  • 刚换出的页面马上又要换入主存,刚换入的页面马上又要换出主存,这种频繁的页面调度行为成为抖动
  • 如果一个进程换页使用的时间多于执行时间,则这个进程处于颠簸
  • 发生抖动的主要原因是,某个进程频繁访问的页面数,高于主存可用的物理页数目

四 文件管理

在这里插入图片描述

  • 文件是以计算机硬盘为载体的,存储在计算机上的信息集合。系统运行时,计算机以进程为基本单位进行资源的调度和分配;在用户进行输入、输出时,以文件为基本单位
  • 文件系统用于实现用户对文件的访问、修稿、保存、维护管理等要求

五 I/O管理

解读I/O多路复用技术
100%弄明白5种IO模型
I/O多路复用详解
在这里插入图片描述

1 同步与异步

  • 同步是指用户发起IO请求后,需要等待或者轮询内核IO操作完成后才能继续执行
  • 异步是指用户线程发起IO请求后继续执行,当内核操作完成后会通知线程或者调用用户线程注册的回调函数

2 阻塞与非阻塞

  • 阻塞是指IO操作需要彻底完成后才返回到用户空间
  • 非阻塞是指IO操作被调用后立即返回给用户一个状态值

3 I/O模型:同步阻塞I/O & 同步非阻塞I/O

同步阻塞I/O

  • 在应用调用 recvfrom 读取数据时,其系统调用直到数据包到达且被复制到应用缓冲区中或者发送错误时才返回
  • 整个请求过程中,用户线程是被阻塞的,对CPU资源利用不够
  • 服务器单线程情况下,无法处理并发的请求;服务器多线程时,为每个请求创建一个线程,造成资源浪费

在这里插入图片描述

同步非阻塞I/O

  • 如果缓冲区没有数据的话,就会直接返回一个 EWOULDBLOCK 错误,不会让应用一直等待中。在没有数据的时候会即刻返回错误标识,意味着如果应用要读取数据就需要不断的调用 recvfrom 请求,直到读取到它要的数据为止
  • 用户线程的轮询操作消耗了大量 CPU 资源
    在这里插入图片描述

4 I/O模型:I/O多路复用

  • I/O = 网络I/O,多路 = 多个TCP连接,复用 = 复用一个或少量线程(很多个网络I/O,复用一个或少量的线程来处理这些文件描述符fd
  • 实现思路是,由一个线程监控多个网络请求(fd,文件描述符,Linux 系统把所有网络请求以 fd 来标识),这样只需要一个或几个线程就可以完成数据状态询问的操作,当有数据准备就绪之后再分配对应的线程去读取数据,节省大量的线程资源
  • 系统提供了一种函数可以同时监控多个 fd 的操作,避免为每个 fd 创建一个对应的监控线程。在 Linux 下包括三种函数:select, poll, epoll
  • 进程将一个或多个 fd 传递给 select,阻塞在 select 操作上,由 select 侦测多个fd是否准备就绪,当有 fd 准备就绪时,select 返回数据可读状态,应用程序再调用 recvfrom 读取数据

在这里插入图片描述

select poll epoll

select & poll

  • 都采用轮询的方式,时间复杂度O(n),随着连接数的增加性能急剧下降
  • select 底层采用数组,有最大 fd 数限制1024;poll 底层使用链表,无最大 fd 限制

epoll

  • 采用回调 callback 而非轮询(被动通知而非主动轮询),时间复杂度O(1)
  • 具有 EPOLLLT(默认)EPOLLET 两种模式
    • EPOLLLT,系统中一旦有大量无需读写的就绪文件描述符,它们每次调用 epoll_wait 都会返回,这大大降低处理程序检索关心的就绪文件描述符的效率
    • EPOLLET,当被监控的文件描述符上有可读写事件发生时,epoll_wait 会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用 epoll_wait 时,它不会通知,即只会通知一次,直到该文件描述符上出现第二次可读写事件才会通知。这样系统不会充斥大量不关心的就绪文件描述符

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

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

相关文章

西门子触摸屏脚本程序_通过驿唐PLC501远程下载Smart Line触摸屏

通过驿唐PLC-501远程下载Smart Line触摸屏一、触摸屏设置将PLC-501和Smart 700 IE V3通过网线连到一起。触摸屏上电后,点击Control Panel进入控制面板界面。进入控制面板后,点击Ethernet设置IP地址,与PLC-501联网宝在同一个网段。联网宝的IP地…

.NET for Apache Spark 1.0 版本发布

.NET for Apache Spark 1.0 现已发布,这是一个用于 Spark 大数据的 .NET 框架,可以让 .NET 开发者轻松地使用 Apache Spark。该软件包由微软和 .NET Foundation 牵头,经过大约两年的开发。在 2019 年的 Spark AI 峰会上,微软曾宣…

fillrect不填充被覆盖的区域 mfc_quot;条带覆盖quot;猜想的中二证明:quot;球面条线覆盖或点覆盖quot;积分π...

注销:“黎曼猜想”复平面质数单向“虚”圆柱螺旋:几何法证明,技术应用​zhuanlan.zhihu.com假设有这样一部针点打印机从球心对球面打印,外部有一台蓝牙打印,球面打印蓝牙条带打印同步,球面被覆盖&#xff0…

让你变厉害的7个底层思维

职场&认知洞察 丨 作者 / findyi这是findyi公众号分享的第89篇原创文章如果把你的思维比做操作系统,那思维模型就是一个个App。这些App会给你提供新的视角,快速帮你决策,提升你的工作效率。顶级的思维模型能提高你成功的可能性&#xff0…

后端学习 - 计算机网络

文章目录一 基本概念1 计算机网络体系结构2 时延二 应用层:HTTP1 请求和响应报文、常见 header2 URL & RESTful API3 HTTP 协议通信过程4 HTTP 方法5 HTTP 状态码6 短连接、长连接与流水线7 Cookie8 Session三 应用层:HTTPS1 加密方式2 证书认证四 应…

跟我一起学Redis之Redis配置文件啃了一遍之后,从尴尬变得有底气了(总结了一张思维图)...

前言秋高气爽的一天,那时候年轻帅气的我正在参照着搜索引擎写代码,迷之微笑般的敲着键盘(又从搜索引擎上找到代码案例啦),突然领导在小隔间里传来了呼唤声,然后有了以下场景:领导:小Z,你过来一下…

1093芯片做正弦波逆变器_长途自驾游“缺电”如何选购正确车载逆变器,避开商家套路...

让车友三分钟就能看明白如何选择车用逆变器,节约车友时间。长途自驾游充电是一个难题,手机充电还好办,其他笔记本、电饭煲、车载冰箱或者无人机电池等充电就会用到220V电源,那就必须用到逆变器(逆变器就是将12V或24V直流电&#x…

Spring 相关问题

文章目录Spring1 Spring 框架中用到的设计模式2 Spring 事务、隔离级别3 单例 Bean 是线程安全的吗Spring IOC1 Spring 容器:BeanFactory & ApplicationContext2 依赖注入的两种方式3 Bean 的生命周期4 依赖注入的四个注解5 如何解决循环依赖Spring AOP1 基本概…

ndr4108贴片晶振是多少频率_关于山羊挺身你知道多少?这些干货速来了解一下...

就是因为有些人愿意吃苦,有些人缺乏决心毅力,才会有成功和失败之分。身材不是一天不运动或一天乱吃所造成,瘦身健身的效果也不是一天的努力可以看出来的。如同学业、事业,成功都不是一条直线,而是一条上上下下的崎岖路…

BeetleX之Websocket服务使用

BeetleX.FastHttpApi不仅是一个Webapi服务组件,它同时也是一个Websocket服务组件。由于BeetleX.FastHttpApi的实现是直接支持Websocket Upgrade操作,所以当启动服务后是HTTP还是Websocket完全取决于请求方;其原理和aspcore一样,同…

typeorm_Nestjs 热更新 + typeorm 配置

Nestjs 开发环境热更新的方案Nestjs 的热更新是基于 Webpack HMR(Hot-Module Replacement) 方案警告请注意,webpack不会自动将您的资产(例如graphql文件)复制到dist文件夹。同样,webpack与glob静态路径(例如TypeOrmModule中的实体属性)不兼容。1 使用 CL…

缓存一致性和跨服务器查询的数据异构解决方案canal

当项目的请求量上去了之后,通常有两种做法来应对高并发,第一是尽最大可能的使用cache来对抗,第二是尽最大可能的分库分表对抗。。。说起来容易,做起来并不那么乐观,这一篇就来浅析下。一:如何保证缓存一致性…

synchronized 实现原理

参考链接 文章目录一 基本使用1 三个作用2 三种用法二 同步原理1 监视器 Monitor2 synchronized 用于同步代码块3 synchronized 用于同步方法3 Mark Word4 对象头的 Mark Word 和线程的 Lock Record三 锁的优化1 自旋锁2 锁消除3 锁粗化4 偏向锁5 轻量级锁、重量级锁以及三种锁…

开头th_是什么文件_Python文件读写最详细的讲解

本文来自公众号:可乐的数据分析之路今天这篇文章来详细讲解一下Python中的文件读写。1、文件读写的流程1)类比windows中手动操作txt文档,说明python中如何操作txt文件?① windows中手动操作txt文件的步骤找到word文档打开word文档查看(或操作…

把 Console 部署成 Windows 服务,四种方式总有一款适合你!

一:背景 1. 讲故事上周有一个项目交付,因为是医院级项目需要在客户的局域网独立部署。程序:netcore 2.0,操作系统:windows server 2012,坑爹的事情就来了, netcore sdk 一直装不上,网上找了资料…

AQS ReentrantLock 实现原理

参考链接 文章目录1 AQS (AbstractQuenedSynchronizer)2 Lock 接口与显式条件3 转账 Demo:解决死锁的两种方案4 ReentrantLock 非公平锁加锁流程5 ReentrantLock 和 synchronized 的异同6 ReentrantReadWriteLock1 AQS (AbstractQuenedSynchronizer) 基于 AQS 的同步…

TensorFlow 2学习和工业CV领域应用 心得分享

我是一名来自苏州的机器视觉开发者,从事传统的机器视觉算法开发有11年了,从2018年开始,因为一些复杂微弱的瑕疵检测项目遇到的传统算法瓶颈,开始接触到了深度学习,并选择了使用TensorFlow,期间也是不断摸索…

历史版本_新版本爆料第弹丨英雄练习新去处,荣耀历史秀出来!

《万物有灵》新版本即将到来新版本来临之前妲己宝宝给自己定下了2个小目标!via.小五怎么不开心目标一扩展自己小得可怜的英雄勺成为一名拥有英雄海的补位大神目标二通过自己的实力获得N1个响当当的荣耀称号很多召唤师会有疑问:凭妲己宝宝的实力&#xff…

循环遍历多层json_面试官:JSON.stringify() 实现深拷贝有什么问题

为什么要进行深拷贝JS中的变量在内存中存储分为值类型和引用类型: 值类型: 1、占用空间固定,保存在栈中; 2、保存与复制的是值本身; 3、基本类型数据是值类型(String,Number,undefined,Boolean,Null&#x…

.NET架构小技巧(6)——什么是好的架构

首先声明,可能本篇文章的含金量配不上这个标题,因为说起架构,可能大家都比较关注高大上的架构,比如分布式的,高并发的,低耦合的,易扩展的等等,本篇可能使你失望了,因为这…