Go+MySQL阶段考核总结
阶段时间:2021年8月12日~2021年9月16日
Golang基础知识博客:go基础博客
这个阶段我学习到了Go基础和mysql,考核总体一般,因为有一些概念没有弄清楚,我所记到的我考核的时候,我不清楚的知识点有:
go基础方面:
gc
interface
类型断言使用
http编程
原子操作
线程和协程的关系
mysql方面:
内外连接语句不熟
关系型和非关系型的区别
MyIsam与innoDB的具体区别
考核后的学习:
gc:garbage collection(垃圾回收)
golang本身支持gc,gc的实现也主要通过以下方法:
三色标记法
后台并发标记
后台并发消除
混合写屏障
辅助gc
每个方法的具体步骤就不在这里详述了。
interface与类型断言:
接口是一种类型,一种抽象的类型,是一组方法的集合,是duck-type programming的一种体现
接口类型的变量可以接收任意类型的值,想要实现可以存储多类型的数组或者map就很方便。
想要判断空接口中的值这个时候就可以使用类型断言
x.(T)
其中:
x:表示类型为interface{}的变量
T:表示断言x可能是的类型。
该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,
若为true则表示断言成功,为false则表示断言失败。
packagemain
import"fmt"
funcmain() {
varxinterface{}
x="pprof.cn"
v,ok:=x.(string)
ifok{
fmt.Println(v)
}else{
fmt.Println("类型断言失败")
}
}
//当然如果条件多的话也可以使用switch语句
http编程
三次握手,四次挥手(每一次的作用):
第一次握手:客户端要求与服务器连接,发送SYN包(SYN=j)到服务器,并进入SYN_SEND状态,等待服务器确认
第二次握手:服务器收到syn包,必须确认客户的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器进入SYN_RECV状态
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态。
完成三次握手,客户端与服务器开始传送数据。
先手中断连接端的可以是Client端,也可以是Server端
(案例:假如先要求中断的是Client端)
第一次挥手:Client端给Server端发信息说没有数据需要传送了
第二次挥手:Server端收到信息之后自己可能还需要发送数据给Client端,所以需要发一次消息让Client端知道
第三次挥手:Server端传输所有的数据完毕,然后给Client端发送FIN报文,表示完成,可以中断了。
第四次挥手:Client端收到之后,发送ACK确认标识,连接结束。
(问题:为什么连接的时候是三次握手,但是挥手的时候却是四次呢?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。)
位码即tcp标志位,有6种标示:
SYN(synchronous建立连接)
ACK(acknowledgement 确认)
PSH(push传送)
FIN(finish结束)
RST(reset重置)
URG(urgent紧急)
Sequence number(顺序号码)
Acknowledge number(确认号码)
原子操作
代码中的加锁操作因为涉及内核态的上下文切换会比较耗时、代价比较高。针对基本数据类型我们还可以使用原子操作来保证并发安全,因为原子操作是Go语言提供的方法它在用户态就可以完成,因此性能比加锁操作更好。Go语言中原子操作由内置的标准库sync/atomic提供。
这个包内有各种各样功能的方法:
读取操作(Load)
写入操作(Store)
修改操作(Add)
交换操作(Swap)
比较并交换操作(CompareAndSwap)
atomic包提供了底层的原子级内存操作,对于同步算法的实现很有用。这些函数必须谨慎地保证正确使用。除了某些特殊的底层应用,使用通道或者sync包的函数/类型实现同步更好。
线程和协程的关系
多个协程可由一个或多个线程管理,协程的调度发生在其所在的线程中。
可以被调度,调度策略由应用层代码定义,即可被高度自定义实现。
执行效率高。
占用内存少。
funcTestGorutine(t*testing.T) {
runtime.GOMAXPROCS(1)// 指定最大 P 为 1,从而管理协程最多的线程为 1 个
wg:=sync.WaitGroup{}// 控制等待所有协程都执行完再退出程序
wg.Add(2)
// 运行一个协程
gofunc() {
fmt.Println(1)
fmt.Println(2)
fmt.Println(3)
wg.Done()
}()
// 运行第二个协程
gofunc() {
fmt.Println(65)
fmt.Println(66)
// 设置个睡眠,让该协程执行超时而被挂起,引起超时调度
time.Sleep(time.Second)
fmt.Println(67)
wg.Done()
}()
wg.Wait()
}
上面的代码片段跑了两个协程,运行后,观察输出的顺序是交错的
意味着在执行协程A的过程中,可以随时中断,去执协程行B,协程B也可能在执行过程中中断再去执行协程A。
看起来协程A 和 协程B 的运行像是线程的切换,但是这里的 A 和 B 都运行在同一个线程里面。它们的调度不是线程的切换,而是纯应用态的协程调度
runtime.GOMAXPROCS(1)
time.Sleep(time.Second)
如果不设置 runtime.GOMAXPROCS(1),那么程序将会根据操作系统的 CPU 核数而启动对应数量的 P,导致多个 M,即线程的启动。那么我们程序中的协程,就会被分配到不同的线程里面去了,故设置数量 1,使得它们都被分配到了同一个线程里面,存于线程的协程队列里面,等待被执行或调度。
因为协程的调度切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。调度发生在应用态而非内核态。
内存的花销,使用其所在的线程的内存,意味着线程的内存可以供多个协程使用。
其次协程的调度不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,所以执行效率比多线程高很多。
比较的点线程协程
数据存储内核态的内存空间一般是线程提供的用户态内存空间
切换操作操作最终在内核层完成,应用层需要调用内核层提供的 syscall 底层函数应用层使用代码进行简单的现场保存和恢复即可
任务调度由内核实现,抢占方式,依赖各种锁由用户态的实现的具体调度器进行。例如 go 协程的调度器
语音支持程度绝大部分编程语言部分语言:Lua,Go,Python ...
实现规范按照现代操作系统规范实现无统一规范。在应用层由开发者实现,高度自定义,比如只支持单线程的线程。不同的调度策略,等等
sql语句使用和记忆不熟练,目前重新记忆了之前做的mysql笔记
关系型数据库和非关系型的区别
关系型数据库:
关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织
优点:1、 易于维护:都是使用表结构,格式一致;2、使用方便:SQL语言通用,可用于复杂查询;3、复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。缺点:1、读写性能比较差,尤其是海量数据的高效率读写;2、固定的表结构,灵活度稍欠;3、高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。
非关系型数据库:
非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合,可以是文档或者键值对等。
优点:1、格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。2、速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;3、高扩展性;4、成本低:nosql数据库部署简单,基本都是开源软件。
缺点:1、不提供sql支持,学习和使用成本较高;2、无事务处理;3、数据结构相对复杂,复杂查询方面稍欠。
MyISAM与InnoDB 的区别
InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;
InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;
InnoDB是聚集索引,使用B+Tree作为索引结构,数据文件是和(主键)索引绑在一起的(表数据文件本身就是按B+Tree组织的一个索引结构),必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。 MyISAM是非聚集索引,也是使用B+Tree作为索引结构,索引和数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。也就是说:InnoDB的B+树主键索引的叶子节点就是数据文件,辅助索引的叶子节点是主键的值;而MyISAM的B+树主键索引和辅助索引的叶子节点都是数据文件的地址指针。
InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快(注意不能加有任何WHERE条件);
InnoDB支持表、行(默认)级锁,而MyISAM支持表级锁
InnoDB表必须有唯一索引(如主键)(用户没有指定的话会自己找/生产一个隐藏列Row_id来充当默认主键),而Myisam可以没有
这两者如何进行选择:
是否要支持事务,如果要请选择innodb,如果不需要可以考虑MyISAM;
如果表中绝大多数都只是读查询,可以考虑MyISAM,如果既有读也有写,请使用InnoDB。
系统奔溃后,MyISAM恢复起来更困难,能否接受;
MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM),说明其优势是有目共睹的,如果你不知道用什么,那就用InnoDB,至少不会差。
最后,还需要定时对基础知识进行复习,避免忘记,之后的计划就是尽快通过缓考课程,进行下一阶段gin以及其他知识的学习,中间也要抽出时间准备四级,今年12月份,必过四级!!!