Linux基础命令

修改权限 #ls命令输出的前两个格式 [d/-/l] [rwx][rwx][rwx] #d说明是文件夹,-说明是文件,l说明是一个链接文件 #第二个是部分是三组权限,从左到右分别对应「拥有者权限」、「所属群组权限」、「其他人权限」 #r是读权限,w是写权限,x是可执行权限,如果没有对应的权限则用-占位 #修改.baserc文件的权限 #第一种数字类型改变权限 #r:4,w:2,x:1; 相加占位 chmod 755 .baserc #第二种符号类型改变权限 #u是拥有者,g是群组,o是其他人,a是上述三个所有 chmod u=rwx,go=rx .baserc #为所有加上可写权限 chmod a+w .baserc #为所有删除可写权限 chmod a-w .baserc 对于纯文件来讲,「写」这个权限的意义是只针对其内容进行修改操作,而不针对其本身的修改(比方说删除这个权限) 对于目录文件来讲,「写」这个权限的意义就不一样了,它针对的是它下面所有的文件(包括目录文件,纯文件)的修改,注意,是对文件的修改

Mysql

必知必会 1⃣️ start、restart、stop mysql.server start mysql.server restart mysql.server stop 2⃣️ 修改密码

unsafe黑魔法

前言 大家应该都知道 Go 语言是不支持指针的运算和转换的。这是为什么呢? 由于 Go 语言是一门静态语言(也叫强类型语言),所以所有的变量都必须为标量类型。不同类型之间不能够进行赋值、计算等跨类型的操作,比方说一个字符串不能赋值给一个 int 类型的变量,一个字符串也不能跟一个整数相加、相减等操作,一个字符串也不能强制转换为整数类型。由于指针也有其对应的类型,所以也在 Compile 的静态类型检查的范围内。同时,静态类型又叫强类型,意思就是这个变量一旦定义其类型,便不能再更改它。 像下面这种,就是不对的 number := 5 numberPointer := &number floatNumber := (*float32)(numberPointer) fmt.Println(floatNumber) 编译器会报错: # command-line-arguments ...: cannot convert numberPointer (type *int) to type *float32 直接翻译就知道这是为什么会报错吧 unsafe 包 用它之前,我们要知道: 它是围绕 Go 程序内存安全及类型的操作 用它写出来的程序很可能是不可移植的 不受 Go 1兼容性指南保护 unsafe.Pointer type ArbitraryType int type Pointer *ArbitraryType ArbitraryType 仅用于来表示任意 Go 表达式类型,就是用来表示任意的含义,他并不属于 unsafe 包的一部分。 所以 Pointer 代表人意类型的指针,类似于 C 语言里面的 void*。

Go Router

Go router 源码分析 先看一下最简单的 web server 服务8: http.HandleFunc("/",func(w http.ResponseWriter,r *http.Request){ w.write([]byte("hello world!")) }) http.ListenAndServe(":8080",nil) 先观察一下这个,这段代码其实就是一个在本地的8080端口的http服务,当访问:127.0.0.1:8080的时候,页面就会输出 hello world! 不难发现,其实只要知道了 http.HandleFunc() 、http.ListenAndServe() 这俩个函数干了什么就知道这个服务是怎么跑起来的了。 那么先查看 HandleFunc() 源码8 hhh 我们就跳到源码里面的 HandleFunc() 里面 func HandleFunc(pattern string, handler func(ResponseWriter, *Request)){ DefaultServeMux.HandleFunc(pattern, handler) } 诶,这里好像继续调用 DefaultServeMux 的 HandleFunc 的方法了昂 那这个 DefaultServeMux 是什么呢? type ServeMux struct{ mu sync.RWMutex m map[string]muxEntry hosts bool } var DefaultServeMux = &defaultServeMux var defaultServeMux ServeMux 找到了定义的部分,发现其实本质就是 ServeMux 结构体. func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { if handler == nil { panic("http: nil handler") } mux.

GO Map底层实现

键值对与哈希表 键值对(key-value pair) GO语言的字典类型其实是一个哈希表(hash table)的特定实现,在这个实现中,键与值最大的不同在于:键的类型是受限制的,而值可以是任意类型的 对键值对的增删改查是通过哈希表映射操作的 比如要在哈希表中查找某个与键对应的那个值,那么我们需要先把键值作为参数传给这个哈希表。 在 GO 语言中每个键值都是由它的哈希值代表的。也就是说字典 map 不会存储任何键的值,但会独立存储它们的哈希值。 1.哈希表会先用哈希函数把键值转换为哈希值。 哈希值通常是一个无符号整数。一个哈希表会持有一定数量的桶(bucket),也可称之为哈希桶,这些哈希桶会均匀地存储其所属哈希表收纳的那些键值对。 2.得到的无符号整数一拆为二,分别称为为高几位和低几位 3.用低几位去定位到一个哈希桶,然后用高几位去定位到具体的键 key 4.随后哈希表就会把相应的元素值作为结果返回 只要这个键值对存在于该哈希表中就一定会被查找到 关于 GO Map 的几个问题 NO.1 字典的键类型不能是哪些类型? 答案是不可以是函数类型、字典类型和切片类型。 GO Map 的键类型的值必须是可以支持判等操作的。由于函数类型、字典类型和切片类型并不支持判等操作,所以字典的键类型不能是这些类型。 另外,如果键的类型是接口类型的,那么键的实际类型也不能是上述三种类型,否则会引发 panic 恐慌。举个例子: var badMap2 = map[interface{}]int{ "1": 1, []int{2}: 2, // 这里会引发 panic。 3: 3, } 由于 badMap2 的键类型是 interface 类型,在编译期间不会报错。但是它的键里面却还是有切片类型 []int{2} 所以在运行时系统会抛出一个 panic 。 NO.2 为什么键类型的值必须支持判等操作呢? 前面说定位到具体的哈希桶之后通过高几位再定位到键,那么是如何定位到键的呢? 首先,每个哈希桶都会把自己包含的所有键的哈希值存起来。Go 语言会用被查找键的哈希值与这些哈希值逐个对比,看看是否有相等的。如果一个相等的都没有,那么就说明这个桶中没有要查找的键值,这时 Go 语言就会立刻返回结果了。 如果有相等的,那就再用键值本身去对比一次。为什么还要对比?原因是:不同值的哈希值可能是相同的。这个术语叫:哈希碰撞。 反过来,哈希值一样,键也不一定一样。所以如果这个键类型的值不能判等,那么就无法定位这个键的具体位置了。