Go语言简介
欢迎来到挂壁商店,挂壁仔挂了,现在由你来接管掌柜,希望你能用计算机把商店发扬光大
人脑计算机
- 人脑如何计算如何存储?我们用电来计算和存储模拟人脑
原始部落->现代科技革命:计算与存储(计算机) 初中毕业
人脑->算盘->纸张->电->电路->运算电路->存储电路-> 指令集->汇编&编译->os->vm->编程->磁盘(持久化存储)-> 驱动->数据库(特殊文件,id映射偏移)
- 1.人脑计算+人脑存储
- 2.算盘计算+纸存储
- 3.电算->逻辑算->算数算(n路异或)
- 4.电存->n路触发双稳态->内存
- 5.计算器:计算存储执行+时钟->多条指令&汇编编译
- 6.操作系统:时间片轮转&并发并行&内存分页&驱动
- 7.vm:os之上模拟真机(模拟指令,模拟计算+存储+pc)
- 8.编程->编译真机或vm模拟os上假机器
- 9.断电存储->量子隧穿(禁锢电子)->硬盘 ->驱动(os封装汇编指令集)->io读写 ->文件->数据库(id映射偏移) ->sql(字符串词法分割转偏移api) -> 哈希索引:map[id]=offset -> b+树(node:{id,offset}) 单机: 连线:电线/电磁波/光,发送01(物理层) 数据有格式:协议 链路层:用数电解析01,
2机交互数据: 2根线发0,1,每次只能发几位,不是一条完整信息 100个位代表一条数据,链路层100长度解析一次 网络 tcp传输层:链路层能发helle world 但是对方不能保证是否成功收到1次握手 你要再发给我一次,确认你能收到(二次握手) 单方可以确保能发送,能收到 我再次发给你 对方能发过来,也能接受 第2次:我能发能收,你能发给我,第三次我能发能收,你能发能收
发100个01,然后代表一数据 数电+100,代表一条数据,然后解析, 网络层:ip tcp为了传输可靠规则 http: 固定格式的tcp 你发个http模板字符串 浏览器就知道是个网页显示
100台互联:连3跟线太麻烦, 路由器:通过路由器转发到主机
局域网->公网 很多个局域网连接->公网 你家电电脑->交换机连接->公网
你就是全球通信
电磁波: 物理层:电脑线/手机卡(电磁波)/光(光纤)
初中毕业,自学8年,到现在水平
os:内存分页(内存虚拟化, 一个内存虚拟化很多个进程小内存 进程:一坨内变量上下文 ) 操作系统高并发:一个计算机内核,只能运行一个程序 晶振时钟:1s震荡100w次,高频震荡电,震荡一次通一次电执行一行指令 时间片的轮转: 把时钟震荡拆分成时间片, 差分10s的时钟震荡为10个1s时间片 1时间片给a程序通电,a程序运行1s,1s有1w次时钟震荡 程序a执行1w行 2时间片一直给b程序通电,b不就执行了1w行 我们的机器能并发了,
- 高并行:2个机器同时执行就是高并行
算:io/8路路/发指令相对操作了机器的加减乘除 用排列组合,不同组合代表加减乘除,2位,10|11|01代表 10就是加法的排列,11是3,01是,这是3+1的指令 架构指令集: 存:用电存,电路要表示2种状态(01),双态电路(双稳态) 什么时候存?按下开关就存,把数据锁住,锁存 锁存1位不够,我们要锁存8位,->寄存 为什么按下开关就是存? 因为电路现在有2种状态 就能代表是0还是1, 我要定义1是存,0是不存
此时能运算能存储->计算机
用排列组合,不同组合代表加减乘除,2位,10|11|01代表 00代表加法排列,01代表减法排列, 8位运算 8位指令架构公式=算数操作符号+第一位数+第二位数 模拟商店买挂面和盐2+5 2+5=00 00000010 00000101 (底层带进位的异或加法器) 计算器他是不是有线,18条线 18条线对应的地方通电,然后就能算出结果 结果是8位:8条线输出
- 现在能用电能算2+5=7=00 00000010 00000101
- 00指令编号为add代码
- 01指令编号位sub代码,代表减法
- 指令集编号人类首次发明了编码,代码
- add 2 5现代编程的雏形 异或能用做1加法, 人脑模拟多为加法,冯2进一补0
- 电如何识别代码add 2 5
- 编译:add 2 5->00 00000010 00000101
- 18位指令当成电线,1就是对应的电线通电
- 你可以用高级语言写编译器,编译add为自己指令
- add 2 5
- sub 9 1 现在我们有计算机了,但是手动按的 用户买单,我按一下add 2 5 用户2买单,我再按一下add 2 5 太麻烦了,
- 时钟:一直发高频脉冲
- 用户买单,喊算账了,时钟帮我们执行add 2 5,就执行了
- 现在不只有算账,还有减库存
- 在喊时钟减库存了,时钟帮助我们sub 100 1 用户1买单,我们就喊2声,算账了,减库存了
能不能喊一声算账了,自动执行add 2+5和sub 100 1 现在我们有计算器,存储器,时钟 思考如何一次执行2个运算,算账和减库存? 先把2条指令存在存储器, 所有我们必须定义个行数叫pc(program counter) 作用:记录我们运行到第几条指令了 时钟一直在震荡运行计算机 时钟震荡第一次,pc为1,拿出存储器中第一条add 2 5 算账 addi pc 1,运行一条指令,程序行数pc+1 时钟震荡第二次,pc为2,拿出存储器中第二条sub 100 1 减库存 时钟=定时器,周期性通电 时钟怎么震荡,周期性通电 晶振:就是玻璃放到电路里面, 敲一下玻璃玻璃震荡非常快,放入电路 产生周期性震荡脉冲电路, 点一下pc从存储器中拿个一个指令 有指令就能执行算数运算 算完第一行,pc+1,到第二行 震荡周期脉冲又来通电了, pc到到第二行指令,运算器执行 一个程序,就能执行多条指令
现在只要电路,能运算的电路, 能存储的电路,能周期执行的电路(晶振) 满足这三个条件的电路就能一次 执行多个指令(程序) 命令:人脑计算模拟结账 算数算账:人脑算账7块,加法,减法,乘法,除法, 逻辑算账买2送一,逻辑运算,与或非异或 存:算完账写入账本(张三7块钱买了1个苹果一个香蕉, 送了一个梨子),写入存储,读取存储,io
指令=计算+存储 java,c,c++,python,javaScript,C#,Ruby, PHP,Go,Rust,Swift,Kotlin,Dart,C++, 、C,C#,Java,Python,Ruby,PHP,Go,Rust, Swift,Kotlin,Dart,C++,C,C#,Java,Python, Ruby,PHP,Go,Rust,Swift,Kotlin,Dart,C++, C,C#,Java,Python,Ruby,PHP,Go,Rust, Swift,Kotlin,Dart,C++,C, window架构指令集010201021,加 linux架构指令集11001021,加 手机架构指令集10111021,加 add 2 5 汇编指令集为代码(人类第一次发明代码) 编译 汇编,c->(交叉编译不同)指令集010201021 静态编译很麻烦,而且不能运行时改变代码(动态)
- 虚拟机器(vm):
- 操作系统之上:在不同系统安装vm,然后运行代码,不需要交叉编译
- jvm,v8,js core,cpyhon很多vm
- 在操作系统之上,运行一个代码模拟的计算+存储系统,
- 用于模拟真实计算+存储电路的机器
- 用vm虚拟机器,模拟计算+存储系统,模拟多指令运算
- vm实现:模拟真机
- 模拟指令集,ir 中间指令集
- java的ir就是class中间指令集
- 模拟中间指令集(ir):add,sub,mul,div,load,store,halt
- 模拟机器存储,内存(难度降为打击),
- 模拟计算:ir指令集 load,beq(假汇编)
- 模拟pc:内存一个变量
- 模拟时钟:不需要模拟
00年初中毕业
一次就能执行2条
计算+存储+顺序执行=计算机 指令集架构编码就叫汇编 汇编变成指令->编译
电路能运算又能存储,他是什么东西? 这东西就是计算机
- 作用:计算和存储数据
- 计算与存储:挂壁仔小刚下单买了一包2块钱的盐,一把5元挂面结账,你需要计算 人脑计算2+5=7,然后小刚付款7元走了,为了防止纠纷和库存不足 你又在人脑中存储小刚买了一包盐,1把挂面, 7元,100的库存减一还剩99, 随着订单量变大,人脑计算太慢也无法 记住那么多订单,因此你学会了用计算器算账,用户每次下单,你用计算器计算,然后在用笔写在账本, 这样加速了计算,并且能永久存储了,如1月1号,用户2购买3斤苹果,消费了9元,库存还剩98
为什么算完账了要记录到本子上?
- 1.计算器是电器,只能计算无法存储,用本子额外存储
- 2.额外存储是为了持久化,防止赖账,进货方便
- 人脑计算机,计算,存储慢,无法持久化
- 出现计算器,能加速人脑计算,但无法存储
- 3.额外写在本子上,永久记忆,
- 比人脑计算机牛逼了,但是还是麻烦
人脑计算机
- 1.人脑计算机,计算慢,无法持久化
- 2.算盘+本子 算盘加速计算,本子存储
- 思考,算盘如果自带存储是不是很方便?这样不是更方便了?
- 思考,如何让算盘能够存储数据?
- 回到古代偶然间被闪电击中,发现了电
- 电,他有什么用了?我感觉闪电只能把我电死
- 你在铜管上挂了一个青蛙,不小心碰了铁管
- 这个青蛙的腿竟然动了?
- 铜管和铁杆电荷不一样,通过青蛙产生了电动势
- 电荷会从浓度高的地方流向低的地方,产生了电流
- 电原来是静止的,闪电,首次让电流动起来
- 1.电流之间加上物体串联,并联构成了电路/
- 电流通过金属发热,发现了电灯,电炉
- 电机=电动机(风扇),发电机(和计算机关系不大)
- 电能不能代替算盘?
- 逻辑门 与门, 或门, 非门,异或门
- 与门都为1返回1
- 你想办法构建一个电路,输入2个高电压,才能输出一个高电压,就是与门
- 或门:2条电路有一个高电压返回高电压
- 非门:取反
- 异或门:不相同返回高电压
- 这是人类实现用电进行逻辑运算
- 机器首次用电表示逻辑运算,以前只有人能逻辑运算
- 现在能用电逻辑运算了,但是我不能算数运算啊?
- 我的商店要加法,盐+挂面结账,
- 偶然间发现异或逻辑门能做1位加法加法运算
- 异或门:不相同的2个逻辑组合返回1
- 00=0,10=10,01=1,00=0
- 0+0=0,1+0=1,0+1=1,0+0=0
- 第一次发明了用电进行1位数加法运算
- 人脑计算机是要算2+5,但是我现在只能算0和1的加法
- 思考:如何让电路,计算2+5=7然后才能付款?
- 1位扩为多为,用二进制表示数字,
- 二进制:,10进制是逢10进一补0
- 0,1,
- 2怎么用二进制表示?
- 2=10,从0数到2,然变成1补0
- 商店店主要用2进制表示2和5然后多位计算,用户才能结账
- 2=10,5=101
- 2+7->10+111
- 110 人脑运算多位加法
- 111 人脑逢2进一位补0 1001
- 刚才用异或门电路发明了1位加法
- 电如何运算多位加法?
- 异或门去模拟人脑加法
- 异或输出后要进位传给下一位,
- 再操作又进位传给下一位,
- 1->8 我能就能运算8位,
- 用电运算2+5轻轻松松
- 补码:减法就是+补码=先算补码然后加法
计算机
- 作用:代替人工计算和存储的电子设备
- 人脑计算机:语法简单,学习成本低(相较于 Java 可降低 2~3 倍)
基础:一个月达到初级程序员(能搬砖水平),薪资10k左右
路线:go基础,web服务,数据库,单体项目,面试八股文,工作完全够用
进阶:3-6个月达到中高级程序员,薪资10-20k左右,20k以上看造化
路线:按顺序学习,标记为进阶的有难度,又很少用到,自主选择学习
1.1.1 Go 简介和特点
Go 是 Google 打造的一门编程语言,有以下特点:
- 简约:语法简单,学习成本低(相较于 Java 可降低 2~3 倍)。
- 高并发:Go 通过轻量级协程goroutine和 非阻塞 I/O,适合高并发网络服务和分布式系统。
- 低内存占用:相较于传统线程模型,goroutine 内存占用小,可同时运行数十万协程。
- 静态编译二进制:打包独立可执行文件,无需依赖运行环境,便于跨平台部署。
1.1.2 Go 擅长的领域
- 高并发服务端开发
- 微服务与分布式系统
- 高性能框架
- 云原生与容器化平台
- 区块链
数据库:
硬盘:(通电存储->断电存储)
什么是数据库?有何用?
持久化存储数据的东西就是数据库
内存,断电就没了
刚才我们用电路实现内存了
存:用电存,电路要表示2种状态(01),双态电路(双稳态)
通电后电路有2种状态,双态,一种表示0,一种表示1
此时双稳态电路通电能存1位数据
非门电路取反,双非门
双非门能2种状态能表示0,1
写入(锁存)
什么时候存?按下开关就存1,把数据锁住,锁存
锁存1位不够,我们要锁存8位,->寄存
8个连在一起,能存8位
存储香蕉2块钱,00000010
存苹果5块钱,00000101
8个双稳态+开关能存1-256(2的8次方)
断电就没了,量子隧穿
加上电场,电子会穿过绝缘层
把电子困在绝缘层里面容器,代表1,没困就是0
存数据,电子通个电场,然后电子一直卡在绝缘层房间
代表永久存储,断电电子都出不来
跨时代意义通电存储->不通电存储,数据持久化
量子隧穿存0和1代替双稳态锁存
8位个这样的装置连起来能存8位(1-256)
8就是8比特,能存1字节Byte
1024字节连起来->1kb
1024kb连起来->1M
1024m连起来->1G
1024G连起来->1T
此时我们发明了1t硬盘
硬盘读写:100110101 代表给这些线通电
然后我们就能持久化数据了
100110101->汇编wt
mov ah, 0x02 ; 功能号:读扇区 mov al, 1 ; 读取1个扇区 mov ch, 0 ; 柱面0 mov cl, 1 ; 扇区1 mov dh, 0 ; 磁头0 mov dl, 0x80 ; 第一块硬盘 mov bx, 0x7c00 ; 缓冲区地址(假设为0x7c00) mov es, bx mov bx, 0 int 0x13 ; 调用中断 jc error ; 如果出错(进位标志置位)则跳转到错误处
go io驱动,汇编,编译就回到磁盘读写指令集
驱动用跨平台语言封装指令集汇编,
抽象成io接口,read,write
go语言上场存储苹果价格5
ioutil.WriteFile("output.txt", []byte('5'), 0644)
文件和数据库的关系?
数据库内核:数据库是特殊格式的文件
用户下单完成后要记账,存储订单 order.txt 代表用户表
订单编号,用户编号,订单金额,订单状态
1 1 5 已支付
2 2 10 未支付 数据大小分割(一行占多大字节)
表结构,id ini 32 user_id int 32
total int 32status int 32- 一条数据=32+32+32+32=128位bit/8=16字节
- 一条数据=16字节,
- 那么我们每次按18字节存储文件,分割每一行
- 这就不就是数据库中的一行
- 店多个记账业务
- 1 1 5 已支付
- 2 2 10 未支付
此时数据库能存储多条订单了,但是读不出来
思考何读取用户id位2的订单?
映射
数据库如何区分每一行?一行大小,磁盘偏移
磁盘能瞬间读取任何的偏移O(1),指针可以偏移移动
读取0-16字节的偏移,此时是用用户1的订单吗?
16-32字节的偏移,此时是用户2的订单吗?
32-48字节的偏移,此时是用户3的订单吗?
映射:
16->1 16号字节偏移是用户1的订单
32->2 32号字节偏移是用户2的订单
48->3 48号字节偏移是用户3的订单
增加映射系统:
存入用户1订单后,插入一条16偏移到用户id1的映射
存入用户2订单后,插入一条32偏移到用户id2的映射
存入用户3订单后,插入一条48偏移到用户id3的映射
业务:用户2张三赖账要退钱,那么我们直接拿出账本证明
张三是2,order.map_exec('查询',2),拿到32字节偏移
磁盘读取32到48的偏移,拿到张三的账本
索引:id到磁盘偏移量的映射
map,map[1]=16,map[2]=32,map[3]=48
如何mysql,pg,
索引->分页页号>页号算偏移>磁盘偏移->拿到数据(回表)
sql:查询语言,一串字符串查询数据,查张三赖账
select * from order where user_id=2
翻译:查询张三是否赖账
张三赖账怎么查?
张三是2,order.map_exec('查询',2)拿到32字节偏移,
磁盘读取32到48的偏移,拿到张三的账本
sql转换成我们的查询张三是否赖账,不就手下sql了吗?
sql字符串,语法分析,你的sql没有错
词法解析:
增删改 查哪个操作?op=查询
查哪个表,拆,table=order
查订单表哪一行啊,我也不知道,用户id=2
用id=2映射到32字节文件偏移,32
select * from order where user_id=1 table.map_exec(op,id)拿到32字节偏移就是用户
map_exec就是所以系统,有人叫回表
sql本质就是字符串转为底层方法和参数
数据库内核:水吗?
-索引就是id到磁盘偏移的映射
hash索引,map[1]=16,map[2]=32,map[3]=484
hash映射,字符串到数字的映射
b+数,node={k,v},k就是id,v磁盘偏移映射
然后把这个node树节点,变成b+数
此时就是b+数索引
node={k,v,pageNo},node->b+树
事务还没读到,以后研究,上班太忙了
b+索引是要持久化,要在磁盘里面
写b+树索引要写磁盘b+数,和内存b+数有区别
科技革命