笔记&问题
先有系统,再编写程序,程序在系统上跑,程序之间还能交互 1系统简介环境:x86-64 linux c从hello word的整个流程
- 看到的人类文本内容,其实是ascII编码组成的?
- 数字代表文本,每个数字又是二进制01表示?
- 文本要gcc编译成二进制执行文件
- 理解内部,才能编程时候更高效--实现一个结果方法很多,总有最好的
- 运行hello ,shell直接run
- 硬件
- 总线 传递信息,以4字节,或者8字节-64位传递,每次?
- I/O设备 通过控制器、适配器与IO设备连接 传数据
- 主存 是芯片存储器 带有地址
- CPU处理器 寄存器程序计数器 处理主存中的指令
- 从主存中加载数据到寄存器
- 从寄存器复制数据到主存
- 运算算术逻辑单元 从寄存器中取出数据计算
- 跳转?跳转执行位置
- 运行过程
- 从键盘复制内容到主存
- 从磁盘加载数据到主存
- 处理器处理,将结果复制到寄存器,结果再传递给显示器
- 硬件
- 数据在磁盘、主存、CPU的寄存器中复制
- 寄存器存的少,主存存的多,磁盘更多
- 但是处理器从寄存器读取最快
- ?kafka顺序磁盘比内存还快
- 但是处理器从寄存器读取最快
- 高速缓存处理器,比主存更快,更接近寄存器
- 寄存器存的少,主存存的多,磁盘更多
- 存储器的层次结构
- L0--最快,但是存的最少,寄存器
- L1-L3 高速缓存 cache?
- L4主存
- L5本地磁盘
- L6分布式文件系统,远程服务器文件
- 分布式的不都得这样吗?
- 操作系统是中间层,把应用系统和硬件分离开
- 文件
- 就是字节序列 ?但不同的文件格式又是?
- 每个IO设备,都能看成文件?
- 虚拟内存 java虚拟机也是包含这些部分
- 每个进程看到的一样。?如果主存不够用怎么办。包含不同的区域
- 程序代码,全局变量数据
- 堆 ?可动态扩展
- 共享库
- 栈 也可动态扩展
- 内核虚拟内存
- 每个进程看到的一样。?如果主存不够用怎么办。包含不同的区域
- 进程
- 一个运行的程序像是独占所有硬件
- 一个cpu在多个进程间切换,执行不同进程的指令
- 上下文切换
- 进程切换,是内核做的,内核是主存中的一部分,保存每个进程的状态?
- 一个cpu在多个进程间切换,执行不同进程的指令
- 一个运行的程序像是独占所有硬件
- 线程
- 是一个进程中,多个执行单元,共享进程中的指令和数据
- 并发,提高一个进程的效率
- 文件
- 各个计算机之间通信,靠网络--也是文件
- 从主存复制数据--网络适配器--网络--其他机器
- 客户端和服务器端通信
- 客户端也是个计算机
- 总结重要概念
- 系统是硬件和软件的结合体
- 并发concurrency和并行parallelism
- 线程级并发
- 单核处理器---多核处理器、超线程?-1核多路?
- 指令集并行
- pipeline 将执行一条指令划分成不同步骤,硬件每次执行一个步骤 ?spark--job--stage 达到并行计算效果
- 单指令、多数据并行?
- 线程级并发
- 抽象的重要
- 应用程序接口API--封装提供
- 文件是对所有IO设备的抽象
- 虚拟机 是对计算机的抽象
- ?所有的生活中的信息如何统一成计算机语言
- 01信号,就是位bit
- 无符号编码 正整数
- 32位表示int 超过了会溢出
- 不溢出那么计算中就是精确的
- 有符号编码补充负数,含有正负数
- 浮点数 2为单位的科学计数法
- 小数,永远不精确,是近似的
- 无符号编码 正整数
- 信息存储
- 位bit 01信号 ,字节byte 8位的块,作为最小的存储单元;再往大B,kb,Mb,Gb,TB,PB
- 内存就是字节组成的数组,每个字节都有地址--唯一的数字标识
- 指针是一个内存块的第一个字节地址--内存地址
- 十六进制 来表示一个字节 8位--是2进制表示,换算成10位--0--256
- 0-9,A-F 来表示 0x开头
- 字数据大小wordsize?
- 32位机还是64位机,
- 对64位机,虚拟地址范围是0--2 64 -1,程序最多访问2 64个字节?
- ?虚拟地址空间变大?64位有16EB空间
- 不同类型的内容,在32位、64位是多少字节存放有的不一样
- 32位机还是64位机,
- 寻址和字节顺序
- 一个对象要跨越多个字节,连续的字节,对象的地址是字节中最小地址
- 大端法和小端法
- 这么多连续的字节,应该从最高位开始,还是最低位开始
- 大端法和小端法
- 一个对象要跨越多个字节,连续的字节,对象的地址是字节中最小地址
- 字符串表示
- ascii ,unicode,utf-8 ,gb2312不同的编码格式?
- 代码的表示
- 不同操作系统,将同一段代码编译成不同的机器码
- 布尔代数
- 按位进行与或非等运算
- C中的位运算,逻辑运算,
- 位 & | ~
- 逻辑 && || ~
- 移位运算 向左向右移动
- 整数
- 类型
- 无符号数 unsigned
- 每个0--2w-1都有唯一w位的编码
- 补码,complement 相对无符号数补充了负数
- 有符号和无符号数转换
- 强转时候要注意是否范围会溢出
- 大部分使用补码,有符号的,范围更广?
- 扩展位,比如从short到 int
- 实际内部字节变化了,位数都变了。。但表示的值不变
- 截断位,减少位,比如从int 到short
- 内部字节排布也会变 ?都用的补码表示
- 整数运算
- 无符号数相加
- 有可能溢出,4位的两个数相加,如果还用4位表示--即类型不变,那最高位被舍弃了,最终结果是减去2的4次方后的结果
- 补码相加 其实就是有符号的数相加
- 有可能负溢出,正溢出
- 补码的非
- 2进制有很多误打误撞的规律
- 乘法
- 无符号和有符号 ,都要注意太大超越默认类型,会溢出
- 乘以常数
- 直接计算乘法,不如移位效率高
- 向左移动移位,就是乘以2
- 直接计算乘法,不如移位效率高
- 除法比乘法更慢 30个时钟周期?--处理器转一圈?
- 还是移位,向右移动,就是除以2
- 无符号数相加
- 浮点数 除不尽?小数精度是小数点位数吗
- 超级大,或者超级小于0的数 x * 2的y次方
- 二进制小数 ,之前小数10.2,都是10进制的--为什么是10?--用手数数,正好10个一组
- 只能近似的表示一个分数。计算尤其小心要
- IEEE对于浮点数表示
- 对于很大的数字,需要2的很多次方,不方便
- 很复杂,阶数,次幂
- 舍入
- 总是向最靠近的整数去,不如直接偶数?--2.5向偶数舍入是2
- 运算
- 乘法等 ?直接算吗,会不会溢出? 有一些计算规则的
- 单精度和双精度转换,还有浮点数和整数转换会遇到的问题
- 向0取整?向偶数取整?
- 溢出
3程序的机器级表示?程序其实也是文本,也是二进制文件,关键是要有编译器编译,转换成可执行的指令机器代码和汇编语言--人类可读的;机器代码是机器执行的编译器把高级语言编译成机器语言?编译器 高级语言--人类语言? 汇编语言 机器语言?只写代码,不理解底层,就不知道深入调优64位 就能提供2的64方内存地址 ; 32位,只能提供2的32位地址 4GB才?
- x86--64的演进
- 晶体管越来越多能集成在一个芯片上,指令集也越来越丰富 sse--sse2
- intel ARM
- 程序级别的代码
- 编译器把程序编译成编译代码;编译代码基本就是能执行的指令了,相比机器代码只是内容是文本的--更能看懂
- C语言到汇编语言
- 程序计数器 下一步的命令在内存中的地址
- 整数寄存器 保存重要的程序状态
- 条件码寄存器 保存算数或逻辑计算的状态
- 向量寄存器 保存浮点型数据
- 机器代码把内存看成大片的字节数组?
- 程序运行时候的内存都存的什么
- 程序的可执行机器代码
- 操作系统的一些信息?
- 运行时栈--管理过程调用和返回? 进站和出站?
- 内存块--?预先分配的库加载到内存了?】
- 一条指令执行很简单的操作
- C语言到汇编语言
- 指令集来定义好各个指令的格式
- 虚拟地址,就是内存地址
- 代码示例
- 将数据压入栈?先进先出
- 机器语言还能被反编译回汇编语言。。
- 加入main方法,真正有入口和出口, 会有不同的地址范围
- 编译器把程序编译成编译代码;编译代码基本就是能执行的指令了,相比机器代码只是内容是文本的--更能看懂
- 数据格式
- 不同的类型所占用的大小
- 16位 一个字?word?
- 8位 一个字节?
- 要合理的使用不同类型,占用大小不同--当然最小范围越好
- 16位 一个字?word?
- 不同的类型所占用的大小
- 访问信息
- x86-64的CPU包含16个寄存器
- 可以存指针等少量数据
- 每个寄存器保存的数据不同,作用也不同。
- 栈指针,参数,函数返回值,局部临时数据
- 操作数指示符
- 操作数,读取的数据源,或者计算后的结果
- 立即数 -常量常数
- 寄存器里的内容
- 内存引用
- 某个内存地址里的数据
- ?实际保存的是地址?
- 寻址模式
- 通用模式 常数偏移量、基址寄存器、变址寄存器*比例因子(1,2,4,8)
- ?这其实还是内存地址?
- 有起始地址,加上从地址内开始的多少偏移量内的数据?
- 通用模式 常数偏移量、基址寄存器、变址寄存器*比例因子(1,2,4,8)
- 操作数,读取的数据源,或者计算后的结果
- 数据传送指令
- 复制
- mov
- 源数据是立即数,在寄存器/内存
- 目的操作数是一个位置,寄存器,或者内存地址?
- 如果源和目的类型大小不同,会对数据进行位的扩展或者降低
- 不能直接内存到内存复制,中间需要寄存器转换
- 局部变量通常在寄存器中
- 访问寄存器比访问内存快
- 复制
- 压入和弹出栈数据 入栈、出栈--后进先出
- 是一种数据结构,可以添加或删除值
- 最先进入的是栈顶,但是在底部
- 栈和内存的关系?
- 还是也存在内存中,类似于整数等是一种数据结构?
- x86-64的CPU包含16个寄存器
- 算术和逻辑操作
- 过程:加载地址,一元操作--只操作一个数,二元操作--两个数运算,移位?--乘除等更便捷?
- 加载有效地址 loadeffectiveaddress
- 从内存读取数据到寄存器? 还是只是引用地址?
- 控制 顺序执行,条件语句或者循环
- 条件码寄存器 ?保存的条件状态
- 访问条件码
- 跳转指令 遇到某个条件跳转到其他地方
- 跳转指令的编码方式
- pc相对寻址 ?
- 实现条件分支
- 用条件控制 true/false
- 用数据传送 不管if、else都会计算一个变量的值,最后返回变量
- 效率更高 因为处理器是分步骤进行的,如果进行判断--会产生错误的计算,浪费时间
- 循环 能通过if判断+goto跳转实现
- do while
- while
- switch多重分支 相比if--分支更少
- 编译后是 跳转表的格式?
- 过程 面向对象?面向过程? 一系列执行过程?--封装的
- 函数,方法,处理函数--handler都是一个封装的过程
- 运行时栈
- 什么时候用栈?
- 函数所需存储空间超过寄存器能存的大小时候 才用栈
- 栈是一块内存结构?真实存在吗
- 局部变量一般存在寄存器中,能很快使用--又不是长期占用
- 函数所需存储空间超过寄存器能存的大小时候 才用栈
- 什么时候用栈?
- 转移控制
- 是说各个方法之间来回调用时候,能够返回到原来的函数位置执行
- 比如main中调用其他方法,执行完再返回时
- 是说各个方法之间来回调用时候,能够返回到原来的函数位置执行
- 数据传送
- 过程调用,有入参和返回参数
- 参数一般通过寄存器传输,能传递6个整型参数? 那其他类型的参数?
- 再多就要靠栈了。。
- 参数一般通过寄存器传输,能传递6个整型参数? 那其他类型的参数?
- 过程调用,有入参和返回参数
- 栈上的局部存储
- 什么时候用栈
- 寄存器存不下
- 局部变量是数组结构,需要栈的结构?
- 栈也是内存的一部分
- 什么时候用栈
- 寄存器的局部存储空间
- ?寄存器也是都存的局部变量
- 寄存器是所有过程都要使用
- 递归过程
- 栈 --使用时候分配局部存储,返回数据后释放?
- 数组的分配和访问 c是包含指针。。某个元素的地址-内存地址 ?必须连续,更新插入慢
- 基本原则
- 内存中的连续区域 多少个 * 数据类型的字节大小 ?必须提前创建大小
- 第0个元素地址是数组的开始地址
- 指针运算
- 运算后是其他元素的地址? 相比直接用下标计算快吗
- 嵌套的数组 多重数组
- ?一个数组的一片连续地址 多重呢?第二重只能保存上一层的地址了吧
- 比如2重数组,以前一维数组是一片连续地址,现在是多个连续的一片地址
- ?也可以看做是一整片连续地址,分成几份?
- 定长数组
- 不会变的?好提前分配
- 变长数组 ?需要提前保留多大的连续区域
- 基本原则
- 异质的数据结构 一个结构保持不同类型数据?--list能保存不同类型?
- 结构struct 类似java对象--存不同的类型
- 类似数组,也是一段内存连续区域
- 联合union sql中需要是相同字段
- 用不同字段引用相同的代码块
- ?类似于view
- 数据对齐
- 数据大小都是K的倍数? 4/8? 为了能访问时候内存中一次访问
- ?不是8的倍数,就不能连续着内存中
- 数据大小都是K的倍数? 4/8? 为了能访问时候内存中一次访问
- 结构struct 类似java对象--存不同的类型
- 机器级程序中控制和数据的交互
- 指针 ?内存的地址
- 是一个抽象概念,其实不是真实的地址
- 指针的类型,是说他指向的变量的类型
- 指针有值,是某个对象的地址? 对象是?--某个变量
- 用 &创建
- * 引用指针
- 数组和指针 数组也可以用指针变量来引用
- 指针的类型转换 ?他指向的类型能变化
- 指针指向函数 则是该函数第一个指令的地址
- 调试工具GDB 类似于adb
- 内存越界引用和缓冲区溢出 ?角标越界
- 缓冲区溢出 bufferoverflow 存了存不下如此大小的类型数据?
- 对缓冲区溢出攻击 ?地址越界
- 栈随机化
- ?如果相同程序在不同机器上栈结构一样就会被攻击?
- 栈被破坏的检测
- 限制可执行代码区域 读,写,执行分离
- 栈随机化
- 长度变化的栈
- 编译时无法确定栈的大小
- 指针 ?内存的地址
- 浮点代码 对浮点数的计算
- 竟然有独立的寄存器来保存浮点数
- XMM寄存器单独保存浮点数?
- 浮点的传递和转换
- 竟然有独立的寄存器来保存浮点数
- Y86-64指令集结构
- 指令集合?状态,寄存器?
- 指令
- 代码会转换成指令
- 不同的语言编写的程序,最终生成的指令一样?
- 入栈,出栈,move等等--移位?
- 不同的语言编写的程序,最终生成的指令一样?
- 代码会转换成指令
- 指令和字节码能一一对应上?
- 逻辑运算如何实现
- 高低位电压来表示0和1
- 逻辑门
- 是真正的电路中存在的硬件? 还是抽象的概念?
- 硬件控制语言HCL 就是如何描述硬件的语言
- 多个逻辑门组合成组合电路
- 两个0,1的信号就能组合成事件的所有组合,复杂处理?
- 存储器和时钟
- 时钟寄存器控制寄存器加载数据
- 内存 --随机访问存储器
- 有地址来选择读写
- 时钟信号到底是?
- 一个电路信号?来控制电路0还是1?
- 顺序实现 ?一个指令的执行过程
- fetch 取指 从内存中读取指令
- decode 译码 不是把代码编译成机器语言?
- execute执行 一条条指令执行?
- memory 访问内存 读写数据 能直接从硬盘读写吗
- write back 写回 将结果再返回到寄存器
- 更新程序计数器PC
- SEQ的硬件结构 seq--其实就是一个执行顺序?
- 取址 什么地址?
- 译码 还是读寄存器的值?
- 执行
- 访问数据从内存
- 写回 从哪写到哪
- 一个时钟周期是包含了所有过程?
- 流水线 一系列执行过程分成不同的阶段,利用好硬件和资源
- 分成不同阶段,分工执行提高效率
- 但是分的工太多、太长却又降低效率
- 流水线实现过程
- 为了提高两个阶段的效率,会预测跳到哪个阶段
- 尤其if else时候会高效或者低效率?
- 数据冒险
- 是有多个时钟修改同一份数据时候,后面的流程再读就不是准确数据
- ?多线程
- 暂停一段时间,再访问
- 是有多个时钟修改同一份数据时候,后面的流程再读就不是准确数据
- 分支预测
- 不是直接根据某个条件成熟后到某个分支?
- 是直接根据上下文,先直接预测执行某个分支?
- 为了提高两个阶段的效率,会预测跳到哪个阶段
- 代码层面,不同的计算方法效率不一样 复杂度不同
- 根据处理器和程序之间的关系来调优
- 各个指令能并发执行
- 循环,减少内部循环次数
- 提高并行度
- 把一个循环展开成两个循环?
- 什么时候寄存器会溢出?什么是溢出?--是否数据大存不下
- 内存
- 加载 从内存读取到寄存器 所有数据都要读到寄存器处理吗
- 存储 从寄存器写入到内存
- 能用临时变量就不用全局变量?
- 两者存的地方不同?临时在寄存器更快?
- 分类
- RAM randomaccessmemory 随机访问存储器 ?不是主存\
- 断电会丢数据 存储都是电路信号?
- 静态的SRAM 在CPU上的cache?
- 动态的DRAM 就是主存
- 磁盘
- 不是电路信号结构? 扇区,盘面,旋转 像唱片
- 访问时间 大概是2*寻道时间
- 寻道时间 是否是找到最开始的位置--所要访问的数据
- 旋转时间
- I/O总线能连接磁盘和其他设备的数据传递
- 内存总线--CPU和内存之间读写
- 固态硬盘 solidstatedisk ssd
- 顺序读写
- 随机读写 都比顺序读写慢 写比读更慢
- RAM randomaccessmemory 随机访问存储器 ?不是主存\
- 局部性 最近访问的地址或者数据能更快的被访问到
- 时间局部性 空间局部性 最近访问的 上次访问的地址
- 存储技术的层次结构
- Redis是否是主存
- 从快到慢分类
- CPU寄存器
- sram 静态高速
- dram 主存
- 磁盘
- 分布式文件系统 最慢?
- 高速缓存存储器 介于CPU寄存器和主存之间的缓存
- L1高速缓存 sram
- L2高速 介于L1和主存
- L3介于 L2和主存 ?清理内存时候123和这一样
- 高一级的cache会缓存一部分低一层的数据
- 访问时候能从更高cache读取到就命中了
- 不断的清理内存和缓存,肯定让程序更慢--缓存命中率变低
- 利用索引来分组,当数据量大时候能提高查找效率
- 指令缓存i-cache,和数据缓存d-cache
- 写比读更复杂,如何更新到最底层的数据?
- 提高使用内存的效率,来提高程序速度
- 吞吐量,每秒能读到多少数据 越高等级存储器越快
- 利用好局部性
- 空间局部性
- 按照顺序来读,不要随机读
- 时间局部性
- 从内存中拿到一个数据要尽快多次用他?
- 空间局部性
- 符号解析
- 不同的全局变量,局部变量,名字一样?参数不同?--重载
- 不同文件中有相同变量名?--强类型,弱类型
- 静态库,引用时候他们在哪?--缓存着了?
- 不同的全局变量,局部变量,名字一样?参数不同?--重载
- 重定位
- ?是把所有符号、变量等重新组合?
- 生成可以执行的目标文件 class可以直接执行?
- 加载目标文件 classloader?
- 共享库所有要使用的库 在哪存放?内存?磁盘一块空间?
- java能加载本地c++库,javanativeinterface--jni
- 本地共享链接库还能动态更新
- 多个程序共享内存中的一个库
- spark能否共享内存中的所有库?而不是每次启动时候再加载?
- 库打桩
- 把调用的库进行一次封装?
- 异常不止是软件中,硬件中也有控制?
- 有单独的异常寄存器?
- 日常见到的exception处理,底层是调用的系统的异常控制?
- 进程
- process
- 每个运行的程序都运行在某个进程的上下文context中
- 一个独立的逻辑控制流 像是独占cpu 但是确实是分配资源的
- 轮流使用CPU
- 一个私有的地址空间 像是独占内存
- 一个独立的逻辑控制流 像是独占cpu 但是确实是分配资源的
- 每个运行的程序都运行在某个进程的上下文context中
- 并发流
- 两个流的执行,在时间上有重叠,在某个时刻都在执行
- 并发 concurrency
- 地址空间
- 是内存的地址?和计算机位数有关? 2的n次方?
- 进程的内存空间?--有代码,数据保存的堆栈
- 用户模式和内核模式
- 需要更底层的通用的处理,才会到内核中处理?
- process
- 对进程的控制
- 能在程序中捕获到进程号,像Linux中一样处理进程id
- 休眠,回收
- 信号 发送一个信号来控制进程
- 进程是有进程组的
- 并发是针对进程还是线程?
- /proc 很多可看的信息
- 进程是有进程组的
- 内存中每字节数据,都有一个虚拟内存地址,和物理内存地址
- 虚拟内存地址实际是CPU虚拟出来的地址,为了更方便访问内存?--相比直接访问物理地址
- 页表,是物理内存和虚拟内存地址的映射
- 虚拟内存,做内存管理,内存保护
- 内存管理
- 每个进程都有独立的页表,独立的虚拟内存,映射到物理地址
- 内存保护
- 保护一个进程的内存数据不被其他的访问和修改
- 内存管理
- 地址翻译 虚拟和物理地址直接是如何对应和联系
- 虚拟内存的使用只在主存中,高速缓存sram中还是用的物理内存--一方面是小
- 多级页表,像对页表建索引
- ?进程创建时候,分配一套虚拟地址?进程消失时候,虚拟地址会否消失?
- 内存映射
- swap空间 和虚拟内存和物理内存的关系?
- 共享的代码块,库,物理是一份,虚拟空间被不同的进程调用
- 动态分配内存
- 直到程序运行时候,才知道需要多少内存大小?
- 如何给进程分配空间,和释放空间。--分配器
- 堆利用率低的原因--碎片
- 进程内的内存有剩余没有使用
- 进程外的,机器中有剩余,但是不够用--对于一个新申请的进程所需
- ?所以一个excutor申请不要过大
- 用链表来表示一个堆 含有位置信息,是否空闲还是占用
- 来一个保存数据的请求,数据放到哪个堆块中
- 一个堆块是堆的一部分?可以8字节?
- 合并空闲块
- 有释放的块,合并,和前面或者后面的
- 当有请求块,不能满足分配大小时候,开启合并
- 合并还不够时候,要重新向内核申请内存
- ?如何合并,什么时候合并
- 如何实现一个内存分配系统
- 创建初始化
- 被调用时候分配空间--按照规则
- 合并,清理释放
- gc垃圾回收
- 回收的是什么?
- 内存中不用的数据,否则内存不够用
- 按照什么规则回收,从内存的哪一部分回收
- 详细的算法
- mark&sweep 标记清除算法
- 从一分配,内存诞生开始,就标记好整个生命周期
- ?维护所有的数据是否被引用?
- 二叉树,维护被引用的关系?
- 不断循环查看他被使用的次数?
- 何时收集?不够了才收集
- 定时收集?
- 回收的是什么?
- 内存相关的错误
- 数组越界
- 内存溢出oom,不够用 ?这是泄漏?可用内存越来越少,垃圾越来越多
- gc报错?--时间过长,引起其他错误
- 引用指针错误、内存内容没有初始化、缓冲区溢出错误--buffer?-系统的还是程序的?,其他指针和数据理解不深运算时候错误使用
- http通信
- rpc调用对方的方法
第十章系统级iothink:
- 在一个机器上的所有程序,不用http,和rpc如何访问的?
- 还是读取的本地端口把
文件系统
- 各个硬件设备之间都是通过文件io交互的
- 读一个文件的流程
- 打开、位置、读、读完关闭
- 读一个文件的流程
- 文件
- t?磁盘中的,和内存中的分别是什么
- 是有不同类型的,目录、文件
- 如何打开和关闭
- 还得读取到内存,再输入和输出
- 读取时候遇到文件结尾,特殊符号的处理
- 需不需要在应用的内存中进行缓存数据?
- 使用时候更快?
- 还得读取到内存,再输入和输出
- 文件的元数据
- ?iNode也是保存在本地盘把
- 需要保存文件相关的性质:位置、大小,类型?分隔符
- 读取目录内容
- ?只读取包含哪些文件名字,有了文件名-所有文件内容就有了也
- 共享文件
- ?有特征,权限能被所有用户使用和修改
- ?存放特定的位置空间中
- 要维护进程--文件之间的关系表:每个进程都读写到哪了,一个读一个写修改怎么办
- IO重定向
- ?一个文件其实是个地址或者软连接,真实是读取另一个文件
- ?或者两个文件其实都是一个iNode
- 是说>到某文件 其实也是读取和保存把
- 标准io
- ?非错误io
- 一系列标准在底层,让上层各个软件接口能统一的读取
- 各种io函数
- read,write,print,scan,first,last
- 不同的读取位置,方法等
- 基于http传输文件
- 提供一个端口,让其他机器访问,返回数据
---------------
- cs架构客户端--服务器访问模式 手机电脑都是客户端
- ?http访问某机器ip端口,机器返回数据
- ?每回请求返回什么数据,http有规则,不同地址不同数据、格式
- 服务端其实就是查找文件返回想要的数据,只是在远程处理数据,不是直接在客户端
- 这样能为很多其他地方的机器提供服务
- 查找数据返回,从本地磁盘,从内存中,从各个构造出来的数据库中--只是为了更快更好返回数据
- 网络
- ?ip,有全球统一的ip
- ?ip又分配给每个国家,国家分给机器能对应上
- ip是访问的地址,机器提供服务
- 本地局域网,现在ip和机器访问?
- 全球网络,应该有光缆传输把
- 文件包怎么传输的,需要有协议
- ?怎么解析
- 无线网,完全不用光缆行吗
- 文件包怎么传输的,需要有协议
- 全球ip互联网
- 统一维护一套ip,共用
- ?ip的设计有协议,如何分配给个国家?
- ip地址
- ?四位数字连接,1-2位不够?
- ?tcp/ip协议是顶层设计,真正用的时候用哪个协议?
- v4 32位,4个点分割十进制数字
- ?v6 128位 6位数字
- 域名
- ?为了更方便访问,但是哪些ip卖给哪些运营商?
- ?还要维护域名和ip的关系
- ?和ip一样全球都有
- DNS domain nameserver
- Internet连接
- ?全球光缆
- ?无线网是什么信号传输
- 连接,是两个进程之间的连接,client和server每个机器提供一个端口,进行通信
- client也是有不同端口来通信
- 套接字接口socketinterface
- ?最底层的通信方式,上层有http封装更完善?
- 有协议,端口有了就能传递数据
- 地址结构
- ?不是ip:端口模式
- ?socket也是一个打开的文件
- 维护连接的机器,还有传输的过程,进度吧
- socket函数
- 应该包含连接,传输,监听,关闭方法
- connect函数
- 是client发起的,向server端
- ?然后server和client就都维护一个打开的文件
- bind绑定,listen监听,accept接收
- ?都是server端的
- ?绑定是记录一个client进度
- ?listen是不断轮询接口请求,还是来了就处理
- ?accept是接收请求发来的数据
- ?何时关闭,
- ?http每一次请求完就关闭吗
- qps是否就是根据底层socket次数来计算的
- 需要验证host和ip是否能进来取数据吧,安全
- web服务器
- ?真正的提供某些服务的
- 以http文件提供
- 网页,app等的后台数据处理服务
- 提供多种类型的展示,超文本--不止文本,
- http协议,特殊的tcp或者socket来应对不同类型的文件传输
- 返回内容,或者计算后返回内容
- http后的一串表示一个文件的位置--最初
- 现在不一定是个文件了,直接从其他数据库里取出数据
- ?和& ?后表示一个文件名,&表示各个参数
- http事务
- ?从请求到结束的整个流程
- 请求发起--处理--返回--关闭
- ?为何要三次握手才能确认连接成功
- 主要请求和响应
- request各种方法,get、post
- repose也响应返回各种参数,还有请求的是否正确的状态码标识
- ?从请求到结束的整个流程
- 返回动态数据
- 如计算后返回内容,不只是返回一个固定文件-静态文件
- ?包含&的动态参数请求,服务器会产生很多子进程来处理?--不是直接处理?
- 那每一个主进程需要产生多少子进程?
- ?真正的提供某些服务的
- 设计一个小的web服务器
- 无论java、Python还有其他语言的
- 都是封装好的一套:各种框架,语言目的只有一个:
- 根据不同的http请求,处理后返回数据
- 直接从本地磁盘
- 从内存系统中
- 从数据库中
- 计算后,或者直接读取
- 根据不同的http请求,处理后返回数据
- 都是封装好的一套:各种框架,语言目的只有一个:
- ?能够循环的执行http的请求,不是程序中自带的、默认的
- 需要封装一层,循环读取http请求,什么时候长连接,什么时候短连接
- 如何并行的能处理多个http请求?
- java web框架中有做并发处理?
- 需要封装一层,循环读取http请求,什么时候长连接,什么时候短连接
- 无论java、Python还有其他语言的
- 不是服务器默认能抗住多少?
- ?有了网络编程,就会有多个client端请求的时候
- 同时请求怎么处理?
- 以前写Android都不用考虑多个client请求
- 程序默认是client一人一个,但是请求的http是相同的
- 后端程序需要处理多个过来的请求
---------------------
- 内核的并发,应用级别的并发
- 3种方式:进程、io多路复用--?、线程--是一个进行的程序中的并发?
- 基于进程的并发
- 一个程序处理不过来,启动多个相同的程序执行?--甚至加上负载均衡?
- 是主程序不直接处理请求
- 产生一个子进程来处理请求
- ?这样会产生无数的子进程来把
- ?进程之间如何通信
- ?会耗尽资源
- ?父子进程之间需要共享哪些信息
- 客户端的信息?处理过程信息?
- 基于IO多路复用的并发
- ?这只是读写文件的并发把,同时下载文件?--开启多线程?
- ?代替程序实现并发的,不是http处理框架
- ?是Tomcat,nginx,nodejs,tornado等web框架?
- ?为什么还要手动维护线程池
- ?这是基于事件的并发
- 不同的对立的事件进来后能一起处理?
- 基于线程的并发
- ?这个不是自己程序中的多线程,也是web框架实现的?
- 是一个进程中的多线程,能共享数据相比进程
- 也是先一个主线程,然后开启另外线程
- ?同时运行,哪些能共享,哪些不能
- 也是先一个主线程,然后开启另外线程
- 原来web框架实现了这么多,并发就是他实现的
- 是一个进程中的多线程,能共享数据相比进程
- ?如何创建,在不同的语言中实现多线程都类似,都是调用的底层?
- ?共用io读取文件
- 线程的新建,执行,结束都有封装的方法,类似java中
- ?如何设计基于线程的多并发web服务器
- 好多连接过来,一个后端程序如何处理多个请求?
- 是nginx,Tomcat实现的?
- ?这个不是自己程序中的多线程,也是web框架实现的?
- 多线程中对共享数据的修改和查询
- ?多个线程同时修改怎么办,我正在写或者修改--其他线程来读怎么办
- 一个进程中分的不同部分:栈,寄存器等,哪些是线程内部的,哪些是可以共享的
- 全局变量肯定是,本地局部变量--静态的变量也是可共享的、非static的变量是线程自己的
- 用信号量来同步线程
- ?信号量是 同步线程?--同步线程内的数据到本线程
- 是指同时操作一个共享数据时候,会引发synchronize同步错误
- 如何解决?加锁?事务?
- ?那还是并发线程吗
- 加锁或者事务肯定会在操作某个数据时候只有一个线程执行,其他在等待
- ?那还是并发线程吗
- 如何解决?加锁?事务?
- 进度图,反映两个线程分别都执行到哪一步了
- 用二维矢量图表示,危险区是--同时对同一个共享数据操作时候
- 信号量互斥?--就是不安全区域,需要只有一个线程进行操作
- 读写
- 基于预线程化的并发服务器
- ?不是来了请求就创建线程,而是提前有线程池准备好了
- ?后端程序中,哪些需要多线程?--哪些不用?
- ?多个请求过来了,是否真的是这一个程序来处理,还是每个请求被一个单独的程序处理
- 应该是处理http请求时候就是多线程了--谁实现的?程序里没有啊
- 程序的分类:顺序程序--顺序执行就行,不用考虑并发,并发程序--单核处理器处理,并行程序--并发的一种,是多核处理器处理
- 并发问题
- 锁不释放?--一直等待;线程安全?--内部数据会异常?
- 线程安全
- 是指多个线程会同时调用一个函数时候,这个函数是否安全
- 函数有可能操作共享数据
- ?加锁
- 函数有可能操作共享数据
- 是指多个线程会同时调用一个函数时候,这个函数是否安全
- 可重入性 ?是特殊的线程安全函数,因为他内部不使用共享变量
- ?同时调用库函数没事吧--还得看是否调用了共享数据
© 本文版权归作者 ChienHsu 所有,任何形式转载请联系作者。
有关键情节透露