Golang面试总结(六)
对已经关闭的channel进行读写,会怎么样?
当channel被关闭后,如果继续往里面写数据,程序会直接panic退出。如果是读取关闭后的channel,不会产生panic,还可以读到数据。但是关闭后的channel没有数据可读取时,将得到零值,即对应类型的默认值。
为了能知道当前channel是否被关闭,可以使用下面的写法来判断。
if v, ok := <= ch; !ok {// 从channel中读数据,ok表示是否读到数据,ok为false表示未读到数据fmt.Println("channel 已关闭,读取不到数据")
}
还可以使用下面的写法不断的获取channel里的数据:
for data := range ch {// get data dosomething
}
这种用法会在读取完channel里的数据后就结束for循环,执行后面的代码。
linux打包压缩命令
tar [-zcxvf] fileName [files]
复制文件或目录-cp
cp [-r] source dest
Golang面试总结(五)
go的内存分配是怎么样的?
Go的内存分配借鉴了Google的TCMalloc分配算法,其核心思想是内存池+多级对象管理,内存池主要是预先分配内存,减少向系统申请的频率;多级对象有:mheap、mspan、arenas、mcental、mcache。它们以mspan作为基本分配单位。具体的分配逻辑如下:
当要分配大于32K的对象时,从mheap分配。
当要分配的对象小于等于32K大于16B时,从P上的mcache分配,如果mcache没有内存,则从mcental获取,如果mcental也没有,则向mheap申请,如果mheap也没有,则从操作系统申请内存。
当要分配的对象小于等于16B时,从mcache上的微型分配器上分配。
分页显示文件内容-more
more fileName
Golang的面试总结(四)
Go的垃圾回收机制?
GMP模型是golang自己的一个调度模型,它抽象出了下面三个结构:
白色对象:未被使用的对象。
灰色对象:当前对象有引用对象,但是还没有对引用对象继续扫描过;
黑色对象:对上面提到的灰色对象的引用对象已经全部扫描过了,下次不用在扫描它了。
当垃圾回收开始时,Go会把根对象标记为灰色,其他对象标记为白色,然后从根对象遍历搜索,按照上面的定义去不断的对灰色对象进行扫描标记,当没有灰色对象时,表示所有对象已扫描过,然后就可以开始清除白色对象了。
Golang面试总结(三)
goroutine的协程有什么特点,和线程相比?
goroutine非常的轻量,初始分配只有2KB,当栈空间不够用时,会自动扩容。同时,自身存储了执行stack信息,用于在调度时能恢复上下文信息。
而线程比较重,一般初始大小有几MB(不同系统分配不同),线程是由操作系统调度,是操作系统的调度基本单位。而golang实现了自己的调度机制,goroutine是它的调度基本单位。
linux进入指定目录-cd
cd [dirName]
如果文件不存在,go语言如何创建?
import ("OS""path/filepath"
)newpath := filepath.join(".","public")
err := os.MkdirAll(newpath,os.ModePerm)
//TODO:handler error
linux目录中搜索文件(find)
find [path][options][expression]
golang如何获取当前运行的程序路径?
package main
import ("fmt""os""path/filepath"
)func main() {ex, err := os.Executable()if err != nil {panic(err)}exPath := filepath.Dir(ex)fmt.Println(exPath)
}
linux搜索特定内容(grep)
grep的全称是Global Regular Expression Print
golang如何打印struct结构体的数据信息到控制台中?
type Project strcut {Id int64 `json:"project_id"`Title string `json:"title"`Name string `json:"name"`Data Data `json:"data"`Commits Commits `json:"commits"`
}fmt.Printf("%+v\n",Project)
%v 按默认格式输出,
%+v 在%v的基础上额外输出字段名,
%#v 在%+v的基础上额外输出类型名。
linux判断文件类型(file)
file [optiions] 文件名
-v -z -L -f name
python链式函数
可以在一行里面调用多个函数
def add(a,b):return a+bdef subtract(a,b):return a-ba,b = 4,5
print((subtract if a>b else add)(a,b)) #9
linux快速复制、设置属性和备份文件(install)
python差值函数
下面方法在对两个列表的每个元素应用给定函数后,返回两个列表的差值。
def differencence_by(a,b,fn):b = set(map(fn,b))return [item for item in a if fn(item) not in b]from math import floor
difference_by([2.1,2.2],[2.3,3.4],floor) #[1.2]
difference_by([{'x':2},{'x':1}],[{'x':1}],lambda v :v['x']) # [{x:2}]
python 数组转置
巧用zip()对一个二维数组进行转置。
array = [['a','b'],['c','d'],['e','f']]transposed = zip(*array)print(list(transposed))
#[('a','c','e'),('b','d','f')]array = [['a','b','c'],['d','e','f']]
transposed = zip(*array)
print(list(transposed))
# [('a','d'),('b','e'),('c','f')]
linux复制文件到多个目录
echo /home/user/1/ /home/user/2/ /home/user/3/ |xargs -n 1 cp /home/user/my_file.txt
golang短变量声明
每次使用变量时都要先进行函数声明,我们可以使用name := expression的语法形式来声明2和初始化局部变量,相比使用var声明的方式可以减少声明的步骤:
var a int = 10
a := 10
使用短变量声明时有两个注释事项:
短变量声明只能在函数内使用,不能用于初始化全局变量
短变量声明代表引入一个新的变量,不能在同一作用域重复声明变量
多变量声明中如果其中一个变量是新变量,那么可以使用短变量声明,否则不可以重复声明变量。
linux用一个命令创建目录树
mkdir new_foldermkdir -p new_folder/{folder_1,folder_2,folder_3,folder_4,folder_5}