CPU运行指令
CPU运行指令搭建计算机数据不保存,是没有意义的。所以我们需要制造可以保存数据的电路,这个电路既可以读取,也可以写入数据。之前我们所有的电路都是一路向前的,有没有想过把输出接到输入上会怎样?
我们来看一个吃自己的小电路,这是一个或门,我们把输出接回到其中一个输入上。然后再增加电源,给它来一个1,也就是高电压。你看或门的输出变成了1。然后这个1又回到了或门的第二个输入,也就是它把自己的输出又吃了回去。现在,即使我们断开第一个输入,或门的输出也还是1,这样我们就保存了一个1。
但是这个电路有个小问题,就是这个改变是永久性的,只要不断电,那么这个或门的输出就永远是1,这样的话也没啥大用。我们想要一个可以按照需求改变的电路,把这个或门电路拓展一下,我们就得到了这样的一个电路。有2个输入,1个SET,1个RESET。
SET可以让电路保存1,RESET可以让电路保存0。看起来好像可以工作了的样子,功能上没啥问题,就是太费线了。如果要保存8位数据,那么需要8个这样的电路。就需要16根线,来分别控制每个电路的SET和RESET。
这要是存个1024个字节,那就是1024x2根线。1024个 ...
基本运算原理
基本运算原理
我们可以用一个与门、一个或门,来搭建一个2位的加法器。异或门来计算和 ,与门计算进位。
这个电路称为半加器
半加器有2个输入X、Y,2个输出,分别是和以及进位。它能产生进位,但是不能处理进位。这是另一层抽象,我们可以把半加器作为一个元件来使用。我们再进一步,制造一个可以做3位加法的电路。
3个1位二进制数相加,最大值就是1+1+1=11,同样可以用2位保存结果。具体电路实现,我们可以用2个半加器和1个或门来搭建。一共有3个输入X、Y、Z,我们把X、Y输入到第一个半加器,输出的和跟Z一起输入到第二个半加器。然后把两个半加器的进位输入到或门,第二个半加器输出的和就是最终的和,而或门的输出就是进位。
两个进位是不可能同时为1的,因为任意两个输入相加,如果产生了进位,那么和一定是0。再加上一位无论是0还是1,都不会产生进位。
我们把3个1位数相加的所有情况都列出来,一共有8种。然后再把电路拉出来,X、Y、Z是三个输入位,XOR 1跟AND 1组成了第一个半加器,XOR 2跟AND 2组成了第二个半加器,OR 1处理两个半加器的进位,这就是全加器的所有电路。 ...
晶体管构成的逻辑门
晶体管构成的逻辑门三极管有两种,一种是PNP型。用E到B的电流控制E到C的电流,E的电压是最高的。另一种是NPN型,用B到E的电流控制C到E电流,C的电压是最高的。
我们来看一个PNP型三极管的例子,本例的目的,是用三极管控制灯泡的亮灭。
我们先搭建一个包含三极管灯泡及电源的回路,这个时候可以看到回路是不通的。现在我们开始添加其他电路,一个电阻、一个电源加一个开关。我们闭合控制电路的开关,灯泡那个回路通了,灯泡就亮了,这就是三极管作为开关的应用。
如果我们把开关替换为一个麦克风,麦克风本质上也是一个开关,不过它感知的是声音。然后把灯泡替换为一个喇叭,这就形成一个基本的放大电路。麦克风的声音会控制喇叭的通断,并且麦克风的声音会放大到喇叭里。
左侧的这部分电路,称为控制电路。如果我们拿一个方盒子把它盖起来,那么灯泡回路的通断,其实就取决于控制电路的通断。我们把高电压用1表示,低电压或者没电压用0表示。那么控制电路输出1,三极管输出1,灯泡回路就通,灯泡就亮起。反之控制电路输出0,三极管输出0,灯泡回路就断,灯泡就熄灭。输出跟输入是相同的,这种被称为同相器,多用于放大电路
如果我们 ...
Linux汇编-两个汇编文件的调用
两个汇编文件的调用1.asm
12345678910111213141516171819202122section .bssresb 2*32section file1data ; 自定义数据段,未使用“传统”的.datastrHello db "Hello, World", 0AhSTRLEN equ $-strHellosection file1text ; 自定义的代码段,未使用”传统“的.textextern print ; 声明此函数在别的文件中 ; 告诉编译器在编译文件时,找不到此符号也没关系,在链接时会找到 global _start ; 连接器把_start作为程序的入口 _start: push STRLEN ; 传入参数,字符长度 push strHello ; 传入参数,待打印的字符串 call print ; 此函数定义在2.asm中 ; 返回系统 mov ebx, 0; 返回值4 mov eax, 1; 系统调用号1:sys_exit int 0x80 ; 系统调用
2.asm
123456789101112131415161 ...
Linux汇编-编写第一个程序
编写第一个程序编程初体验123456789101112131415161718192021# 目的: 退出并向LINUX内核返回一个状态码# 输入: 无# 输出: 返回一个状态码。在运行程序后通过输入echo $?来读取状态码# 变量:# %eax 保存系统调用号# %ebx 保存返回状态.section .data.section .text.global _start_start: movl $1, %eax # 用于退出程序的linux内核命令号(系统调用) movl $0, %ebx # 这是返回给操作系统的状态码 # 改变这个数字,则返回到echo $?值会不同 int $0x80 # 唤醒内核,以运行退出命令
汇编程序
1as exit.s -o exit.o
上述命令中,as是运行汇编的命令,exit.s是源文件,-o exit.o告诉汇编程序将输出放在文件exit.o中,exit.o称为目标文件。
目标文件的内容通常不完全放在一起。许多大型项目有多个源文件,通常将每个源文件都转换为一个目标文件。链接器将许多目标文件合二为一,并向其中添加信息,使内核知 ...
C之attribute的作用
__attribute__的作用attribute:属性,主要是用来在函数或数据声明中设置其属性,与编译器相关
GNU C 的一大特色就是__attribute__机制。__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。
语法格式为:
1__attribute__ ((attribute-list))
数据声明:
__attribute__ ((packed)): 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,是 GCC 特有的语法。
__attribute__((aligned(n))): 内存对齐,指定内存对齐 n 字节
函数声明:
__attribute__((noreturn)): 的作用告诉编译器这个函数不会返回给调用者,以便编译器在优化时去掉不必要的函数返回代码。
__attribute__((weak)): 虚函数,弱符号
packed
该属性可以使得变量或者结构体成员使用最小的对齐方式, ...
MyISAM 和 InnoDB 的区别
MyISAM 和 InnoDB 的区别
InnoDB支持事务,MyISAM不支持
对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;
InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;
InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。
但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此主键不应该过大,因为主键太大,其他索引也都会很大。
而MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。
InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高;
如何选择
是否要支持事务,如果要请选择innodb, ...
最左前缀原则
最左前缀原则首先是,这个最左前缀原则是发生在复合索引上的,只有复合索引才会有所谓的左和右之分。
当b+树的数据项是复合的数据结构,比如(name,age,sex)的时候,b+数是按照从左到右的顺序来建立搜索树的,比如当(张三,20,F)这样的数据来检索的时候,b+树会优先比较name来确定下一步的所搜方向,如果name相同再依次比较age和sex,最后得到检索的数据;但当(20,F)这样的没有name的数据来的时候,b+树就不知道下一步该查哪个节点,因为建立搜索树的时候name就是第一个比较因子,必须要先根据name来搜索才能知道下一步去哪里查询。比如当(张三,F)这样的数据来检索时,b+树可以用name来指定搜索方向,但下一个字段age的缺失,所以只能把名字等于张三的数据都找到,然后再匹配性别是F的数据了, 这个是非常重要的性质,即索引的最左匹配特性。
B树和B+树的区别
B树和B+树的区别B树,每个节点都存储key和data,所有节点组成这棵树,并且叶子节点指针为null,叶子结点不包含任何关键字信息
B+树,所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接
所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B 树的非终节点也包含需要查找的有效信息)
为什么说B+比B树更适合实际应用中操作系统的文件索引和数据库索引?
1、B+的磁盘读写代价更低。
B+的内部结点并没有指向关键字具体信息的指针,因此其内部结点相对B树更小。
如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。
2、B+-tree的查询效率更加稳定。
由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。
B+树索引和哈希索引的区别
B+树索引和哈希索引的区别B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过1,而且同层级的节点间有指针相互链接,是有序的,如下图:
哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可,是无序的,如下图所示:
哈希索引的优势:
等值查询,哈希索引具有绝对优势(前提是:没有大量重复键值,如果大量重复键值时,哈希索引的效率很低,因为存在所谓的哈希碰撞问题。)
哈希索引不适用的场景:
不支持范围查询
不支持索引完成排序
不支持联合索引的最左前缀匹配规则





