转:Go语言必知的90个知识点

Go语言必知的90个知识点
1. 函数可以返回函数类型
func test() func(int) {
return func(x int) {
println(“x:”, x)
}
}
2. defer定义延迟调用,无论函数是否出错都确保结束前被调用
3. ok-idiom(A跌目)模式:多返回值中用一个名为ok的布尔值来标记操作是否成功
4. 结构中的匿名字段,结构的实例可以直接调用匿名字段的方法和属性
5. 计算机中变量是一段或者多段用来存储数据的内存,类型决定变量内存的长度和存储格式,所以我们只能修改变量值不能修改类型
6. 内存分配发生在运行时,编译后的机器码不使用变量名而是直接使用内存地址访问目标数据,所以编码阶段采用易于阅读的变量名
7. 惯例建议以组的方式整理多行变量定义 var {x,y int } type{ xxx }
8. 简短声明一般用于函数多返回值,以及if for switch等语句中定义局部变量
9. 未使用的局部变量会编译出错,全局变量不报错
10. 命名建议字母或下划线开始,多字母数字和下划线组合,局部变量优先短名
11. 常量实在预处理阶段展开成指令数据,变量是在运行期分配存储内存.(所以常量无法寻址,没有地址)
12. byte是uint8的别名 rune是int32的别名 别名直接可以相互赋值不需要类型转换
13. 拥有相同的底层结构不代表就属于别名
14. new为指定类型分配零值内存返回指针;make是引用类型专用的创建函数(内存分配和属性初始化)
15. 未命名类型:数组、切片、字典、通道等类型与具体元素类型或长度等属性相关的类型,可以用type将其改变成命名类型
16. 对于未命名类型 struct tag不同也属于不同类型,字段顺序不同也属于不同类型。
17. 乘幂和绝对值运算在math包的Pow和Abs中
18. 自增自减只能作为独立语句
19. 指针是实体会分配内存空间,内存地址是内存中每个字节单元的唯一编号
20. 指针类型指向相同地址或nil则相等,但是不能做加减和类型转换
21. unsafe.Pointer将指针转换为uintptr进行加减运算,但可能造成非法访问
22. 指针不能用->,统一使用.
23. 复合类型初始化,必须包含类型标签;左花括号必须在类型尾部;多成员都好隔开;多行右侧必须是逗号或者花括号
24. switch 无需显式执行break,但是想顺序执行需要显式执行fallthrough
25. range迭代是复制数据
26. goto只能跳转到同级代码,不能跨级别
27. break用于switch for select,终止整个语句块执行
28. continue只用于for循环,终止后续逻辑立即进入下一轮循环
29. 函数无需前置声明;不支持命名嵌套定义;不支持同名重载;不支持默认参数;支持不定长参数;支持多返回值;支持命名返回值;支持匿名函数和闭包
30. 函数类型只支持nil判断,不支持其他比较操作
31. 从函数返回局部变量指针是安全的,编译器会通过逃逸分析来决定是否在堆上分配内存;所以参数尽量减少值拷贝
32. 函数建议命名规则:动词+名称;避免不必要的缩写(printError优于printErr);避免使用类型关键字;使用习惯用语(init表示初始化,is/has返回布尔值);用反义词命名行为相反的函数
33. 不管是指针、引用类型还是其天涯类型参数,都是值拷贝传递,区别在于拷贝的目标对象
34. 指针传递坏处在于延长该变量的声明周期,也可能导致他分配到堆上增加性能消耗
35. 函数参数在函数内部有效,作用域是整个函数内部
36. 变参 func test(a …int){} test(a[:]…)
37. 命名返回值的问题: 新定义的同名局部变量会引起同名遮蔽:xx is shadowed during return ;此时实名return即可
38. 闭包 匿名函数能够使用上下文的环境中的数据(最终数据)
39. 延迟调用defer 常用于资源释放 解除锁定 错误处理等 先入后出。 延迟调用开销很大,性能要求高压力大的算法尽量避免使用
40. error是接口类型
41. panic会引发函数中断执行defer ,在defer中使用recover捕获panic提交的错误对象(recover只能在defer中执行才有效)
42. 多个panic仅最后一个被捕获
43. runtime/debug.PrintStrack()可以打印完整的堆栈信息
44. 不可恢复性、导致系统无法正常工作的错误才会使用panic (文件系统没权限操作、服务端口被占用、数据库未启动等)
45. 字符串是不可变字节(byte)序列,可用len获取长度,不可用cap; ` 支持跨行;允许字节数组访问,单不允许字节数组取地址
46. 用切片指向数组时,底层还是指向该字符串
47. range遍历可以打印出汉字,len遍历出的汉字是乱码
48. append可以向[]byte追加 =》var bs []byte bs=append(bs,”abc”…)
49. 字符串加法运算每次都会重新分配内存,构建大字符串性能极差;方法1:strings.Join 方法2:bytes.Buffer 小字符串拼接使用fmt.Sprintf text/template等
50. utf8.RuneCountInString(s)代替len获取带汉字的字符串长度
51. 长度是数组的类型组成部分,元素类型相同长度不同的数组不是同一类型
52. 多维数组,只第一维支持… => […][10]
53. 如果元素支持== !=操作,则数组也支持
54. 数组是值类型
55. 切片:不是动态数组或数组指针;内部通过指针引用底层数组,设定相关属性将数据读写操作限定在指定区域内。可以理解为数组指针的包装
56. 切片本身是只读对象,工作机制类似数组指针的包装 右半开区间 数组必须addressable
type slice struct{
array unsafe.Pointer
len int
cap int
}
57. 切片引用数组时,切片指针会指向数组地址;访问越界会报错;append会追加数组,当长度大于cap时会重新分配地址,则切片和数组就相互独立了
58. 切片 var a[]int 为nil,仅代表他为初始化,但依旧分配内存;且a[:]依旧是nil
59. 如果切片长时间占用大数组的少量数据,建议切片单独分配地址,以让大数组尽早释放
60. 可将字符串直接复制到[]byte => b:=make([]byte,3) n:=copy(b,”abcdefhg”)=>n=3,b=[97 98 99]
61. 字典的key必须支持== != 如数字、字符串、指针、数组、结构、接口
62. if v,ok:=m[“d”];ok{存在} 使用ok-idiom模式判断key是否存在
63. delete(m,”d”),删除不存在的key不报错
64. map使用range迭代每次顺序不定
65. map被设计成 no addressable,所有没法修改value的成员(如果value是个结构或者数组等) ;改进方法1:先获取完整value,修改后再赋值回去;方法2:value采用指针类型。因为value是指针,所有可以通过指针修改指针指向的数据。
66. map并发操作,某任务针对map写操作,其他任务对该map的读写删除都会导致进程崩溃;可用sync.RWMutex实现同步(不要使用defer)
67. map对象本身就是指针包装,传参不需要取地址
68. map创建时和slice一样要预选分配足够地址,减少扩张时不必要的内存分配和重新哈希操作=>make(map[int]int,1000)
69. 对于海量小对象,应该直接用字典存储键值数据拷贝而不是指针,这样减少扫描对象的数量缩短垃圾回收时间。
70. 字典不会收缩内存,适当替换新对象是有必要的
71.

结构推荐命名初始化,以防扩充结构时报错
匿名结构:
u:=struct{
name string
}{
name:”xxx”,
}
72. 只有所有成员都支持==操作时,结构才支持相等操作
73. 匿名字典隐式的以类型名为字段名称,使用时可以直接饮用匿名字段的成员,但是初始化时必须当做独立字段。(但是隐式字段是外部类型的话,隐式名称不包含包名)
74. 除接口指针 多级指针外的任何命名类型都可作为匿名类型
75. 字段标签是对字段描述的元数据,是类型的组成部分;运行期间可用反射获取标签信息,通常作为格式校验和数据库关系映射等
p1:=p{
name:”xxx”,
sex:1,
}
v:=reflect.ValueOf(p1)
t:=v.Type()
for i,n:=0,t.NumField();i<n;i++{
fmt.Printf(“%s:%v\n”,t.Field(i).Tag,v.Field(i))
}
76. reflect.StructTag提供了更完善的功能
77. 前置实例接收参数-receiver
78. receiver是基础类型则会被复制,指针类型则必须能获取实例地址
79. receiver类型选择:不修改的小对象或固定值用T;引用类型、字符串、函数等指针包装对象用T;修改实例状态用T;包含Mutex等同步字段用T,大对象或不确定情况用*T;
80. 匿名类型的方法也存在同名遮蔽的特性。(可实现类似覆盖操作)
81. T的方法集是 receiver T;*T的方法集是receiver T+*T
82. 匿名嵌入S,T包含 receiver S;匿名嵌入*S,T包含 receiver S+S; 匿名嵌入S或S,*T都包含 receiver S+*S;
83. 方法集仅影响接口实现和方法表达式转换。匿名字段就是为方法集准备的
84. Chan:
一次性事件使用chan的close效率更高
向close的chan发数据panic
从已关闭的chan接收数据返回已缓存数据或零值
无论收发,nil通道都会阻塞
85. Chan和锁的选择:
同步问题应该用锁或原子变量来操作
对性能要求较高时,赢避免使用defer unlock
读写并发时,用RWMutex性能更好
对单个数据的读写保护建议使用读写锁
严格测试,尽可能打开数据竞争检查
通道倾向于解决逻辑层次的并发处理架构
锁用来保护局部范围内的数据安全
86. FieldByName不支持多级名称,如有同名遮蔽需要匿名字段二级获取
87. 可用发射提取struct tag还能自动分解,常用于ORM映射或数据格式验证
88. 反射可通过Interface方法进行类型推断和转换
89. 对性能要求较高的地方需要谨慎使用反射
90. Go语言1.5版本实现的自举

Advertisements

Algorithm: Practical Set Reconciliation

《Practical Set Reconciliation》
Yaron Minsky Cornell University https://blog.janestreet.com/author/yminsky/
Ari Trachtenberg Boston University

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.456.7200&rep=rep1&type=pdf

def set_reconcile(src_seq, dst_seq):
    "Return required operations to mutate src_seq into dst_seq"
    src_set= set(src_seq) # no-op if already of type set
    dst_set= set(dst_seq) # ditto

    for item in src_set - dst_set:
        yield 'delete', item

    for item in dst_set - src_set:
        yield 'create', item

for i in set_reconcile([1,2,3,4], [2,3,4,5]):
    print i

$ python set_reconcile.py 
('delete', 1)
('create', 5)

Fedora 29: dbus bug系统无法启动

https://bugzilla.redhat.com/show_bug.cgi?id=1623781
Bug 1623781 – dbus-1:1.12.10-2.fc29 breaks system boot

昨天中午用 `sudo dnf update -y`升级了Fedora 29系统软件,下午开机时卡在登陆界面之前了。内核日志没有啥明显异常,而且还能正常识别USB的插入拔出,所以内核应该没有panic或者死锁。
最后用上下键切换到systemd的日志输出,发现是dbus启动失败。于是从grub里自带的救援模式下,查看了/var/log/dnf.log里dbus更新前的版本号,然后用`sudo dnf downgrade dbus-1.12.10-1.fc29`把dbus降级后就正常了。

在救援模式下不能直接使用wifi,可能是缺驱动或者需要手动加载配置。于是想到用手机通过usb线共享网络,手机就成了一个usb网卡,`if ethx up; dhclient ethx`,网络就正常了。

“寒窑”故事传说

秦腔戏曲名段《王宝钏》家喻户晓,王宝钏居住的“寒窑”就在西安城南曲江附近,现在建有一个遗址公园供参观游览,弘扬传统爱情忠贞观念,需要购买门票。喜欢秦腔的老年朋友,肯定都想过去打个卡。

故事传说
西安城南大雁塔附近的五典坡有一孔破旧的窑洞,窑洞上沿题有“古寒窑”三个字,相传当年王宝钏苦守寒窑十八载,等待丈夫薛平贵归来的故事,就是发生在这里。 [1]
王宝钏是唐朝宰相王允的女儿。王允没有儿子,只有三位如花似玉的干金,两个姐姐都婚配得门当户对,父母也想为待字闺中的小女儿找一位乘龙快婿。
当时长安城南一带,山环水绕,风光秀丽,每到春暖花开的时候,京城长安的皇族显贵、文人雅士、贫民百姓,都喜欢到这里赏花游春。这年春天,王宝钏也带着几个丫环来南郊踏青,不料遇上一伙风流公子追随纠缠。这时,旁边一位衣着陈旧的年轻书生看不过去,果敢上前拦阻这伙人的无礼行为。这些恶少一拥而上,对书生拳脚相加。那书生只略摆架式,轻轻一撞,便把那伙中看不中用的锦衣公子撞得七倒八歪,他们心知不是书生的对手,相扶着骂骂咧咧走开了。
王宝钏暗自佩服书生的功夫和胆略,见那群风流公子走开,连忙上前行礼感谢。书生略有些腼腆,连声说:“理当如此,小姐不必多礼!”书生愈是客气,王宝钏就愈是欣赏他,口中称谢不已,一来二往,两人便熟络起来。这书生只说自己叫薛平贵,父母双亡,家庭败落,只剩下自己一人。在王宝钏看来,这书生不只是武功高强,而且知书达礼,虽然衣着寒酸,却掩盖不住气宇轩昂,不由心生爱慕。于是两人结伴游玩,一路鸟语花香,春气袭人,一种温馨的感觉回荡在两人中间。薛平贵知道了眼前的小姐乃是相国千金,不但容貌姣美,言谈举止又那么娴雅而不矫揉、端庄而不傲慢,确实让他着迷,但又自愧太不般配。日暮分手时,两人眼光中充满眷恋与不舍。
不久,老父又摧促三女儿赶快订下婚事,王宝钏灵机一动,提出了以抛掷绣球来决定终身大事 的办法,王父应允了。宝钏想,自己抛球征婚的消息一传出,有情郎薛平贵一定会赶来参加,到时绣球落哪方就全凭自己决定了。王父暗中决定,到那天院门要把 紧,只放些有身份的公子进来,这抛球的规矩可是“中鸡嫁鸡,中狗嫁狗”的,可不能让那些贫贱小子捡了便宜。于是王家院里搭起了高高的彩楼,订了个黄道吉日 由三小姐抛掷绣球择婿。消息传出后,远远近近的名家公子都争相赶到王家,因为大家早就风闻了 王家三小姐的才貌,又贵为相国千金,都想来碰碰运气。王家的院门果然把持甚严,不是有头有脸的人决不许进。聪明的宝钏让上次同去春游、见过薛公子面的贴身丫环到院外悄悄寻找薛平贵,让她带薛平贵从侧门进院。
吉时已到,一阵锣鼓炮仗响过之后,衣着艳丽的小姐手上托着一个五彩绣球站在楼上。楼下院中披红戴绿的公子哥儿们轰动起来,都伸长了脖子,期待着天赐 良缘。上面王宝钏粉面含笑,玉腕翻处,绣球翩翩落下,不偏不倚,正打在院中一角的布衣公子薛平贵头上。王允一看,绣球抛中的女婿竟是一个衣着寒酸的落拓少 年,当即心中生怒,坚决反对。原本心中喜滋滋的宝钏,明白父亲是见薛平贵贫贱,而不惜违约悔婚。此时,宝钏决意不再任由父亲摆布自己的终身大事,嫁给了心 上情郎薛平贵,王允一怒之下与她断绝了父女关系。这时薛平贵了无栖身之所,于是两人搬进了五典坡的一处旧窑洞。在寒窑中,夫妻俩男樵女织,过着清苦的日子,幸而夫妻间互敬互爱,相依为命,苦日子也过得颇有滋味。虽然王宝钏的父亲与她断绝了关系,而老母却无法割舍这个惹人怜爱的小女儿,不时派人来 探望他们,送些钱物,使他们的生活得以维持下来。咸通九年,桂州边区发生叛乱,攻占了边防重镇,并向北逼进。朝廷出兵讨伐,为了增强兵力,还令沙陀部队随军助战。文武兼备的薛平贵参加了沙陀的部队。王宝钏是多么不愿意自己的丈夫离开,但薛郎是有才有识的伟男儿,总不能与自己终身相守寒窑,她擦掉泪水,为薛郎收拾行装,挥手送他出征。
在沙陀部队中,薛平贵凭着自己出色的武艺和才学,渐渐受到酋长朱邪赤心的重视。剿平了叛乱,薛平贵没有来得及回长安探望久别的妻子,就随军驻进了大同。一次,薛平贵随酋长一家到郊外狩猎,行到山崖时,朱邪赤心的女儿春花公主的坐骑突然受惊失控,扬蹄飞奔,眼看就要坠下悬崖。紧随其后的薛平贵,飞奔向前,伸臂竭力拦住了公主的马匹。两匹马行到山坡上,薛平贵下马扶起受惊的春花公主,正值情窦初开的小公主,见救她的人是一位年轻英俊的汉族勇士,不由地心旌摇晃,就势倒在薛平贵怀里。
从那天起,春花公主就如痴如醉地爱上了薛平贵。薛平贵心里一直挂牵着长安寒窑中苦等自己 的妻子王宝钏,他不愿意背叛她诚挚的爱心。可是自己在沙陀部队里一直默默无闻,若不抓住春花公主这个台阶,以后怕是很难再有高升的机会,何况若是惹恼公 主,自己还不知道能不能在这里呆下去。权衡再三,薛平贵成了沙陀酋长的“驸马爷”,他在沙陀军中的地位自然也就急骤地升高了。当然,他不会忘记结发之妻, 曾多次趁唐廷专使前来大同慰劳之际,悄悄托使者为王宝钏带去书信金帛,接济伊人的生活,当然他没告诉她自己在这里已另配佳偶。而寒窑中的王宝钏始终矢志不移,纺纱度日,一心一意筹待着良人衣锦荣归。一年又一年地过去了,总也不见薛平贵归家的身影,后来竟还断了音信。是薛郎变心了吗?不是,是政局在这时发生了急剧的动荡。薛平贵随沙陀军到了阴山。阴山与长安两地遥遥,不通音讯,薛平贵心想不知何时才能与宝钏团聚。一年,长安情势紧迫,大唐军力不足用,沙陀军入京援战,保住了大唐江山。
薛平贵随军来到长安,功成名就的薛平贵只身步行来到五典坡的寒窑中,终于与分别达十 八年之久的妻子王宝钏见面了。夫妻相见,直从正午呜咽流泪到黄昏。王宝钏终于走出了寒窑,被接入薛平贵府中。经过了十八年的苦盼,王宝钏终于有了一个美满 的家庭。而王宝钏苦守寒窑十八载的故事也被人们传为美谈。

Continue reading “寒窑”故事传说

Input & Output

2007年因为opera博客被封,决定自己注册域名、购买空间,创办个人网站。一直维持个人小站、技术生活大杂烩博客。这些年网络世界发生了翻天覆地的变化,内容背后更多的是网络社交关系。现在分享的平台太多,博客、微信、公众号、medium、简书、twitter、Facebook、音频(如喜马拉雅)、视频(youku\youtube\抖音)、知乎、豆瓣。

周围的朋友,也有很多人通过网络分享精彩的生活,涉及绘画、美食、健身、旅行、育儿等等。百家争鸣,百花齐放!

每个人都是一个系统,可以通过阅读、旅行、社交等等进行输入。然后内部加工(思考)后通过言行进行输出。输出的可能是知识、思想、价值观、生活感想等等。网络也是一个个性展现的大平台,一个更加开放包容的平台。

现在博客写的太少,估计看的人也少,而且基本都是生活相关的。所以索性把博客搬到wordpress.com。我想梳理一下,选择自己擅长的领域,多思考、多对外有高质量的“输出”。