2019年2月

图书保存六忌
作为一个现代化家庭,很重要的一点就是要讲求知识品位。常言说得好,“酒香花香不如书香,藏金藏银不如藏书。”家庭藏书及藏书多少并不是常人所说的为了装潢门面,附庸风雅,而是一个家庭知识品位的标志和象征。对于这方面感兴趣的朋友,笔者倒很愿意谈一谈家庭藏书的忌讳。家庭藏书有以下六忌:
一忌尘。书籍上堆积了灰尘,不但玷污图书,而且灰尘本身还是昆虫、霉菌藏身和繁殖的地方。所以要经常用手轻轻拍弹掉图书表面的灰尘,然后再用专用于擦拭图书的柔软的毛巾,定期对图书表面进行擦拭,以保证图书处于常新的状态。
二忌潮。潮湿是生虫发霉的有利环境,对书的危害较大。所以,至少每半年要在阴凉、干燥、通风处对图书进行晾晒。书柜的柜脚一般要高出地面20厘米,以防家庭积水可能带来的侵害。
三忌虫。破坏图书的害虫很多,常见的有书虱、白蚁、蛾蝶、蟑螂等,还有鼠类和微生物,其中危害最大的是微生物中的细菌和真菌(又叫霉菌)。所以每层图书最好都要置放两粒香樟球或萘丸,以防图书虫蛀。
四忌光。书籍不仅怕阳光,而且还怕荧光灯之类的灯光。主要是光里的紫外线会使纸张老化,纸张的泛黄多半是由紫外线造成的。绝不能让图书直接在阳光下曝晒,那样不仅起不到防潮作用,还会因曝晒图书而直接减少图书的寿命。
五忌热。单是热,书并不怕,但一定的温度加上潮湿,就造成生虫发霉的有利条件。因此,一般藏书的场所总要求低温或空调,对珍贵的图书尤其如此。柜门要定期打开通风、散气,确保图书“肺部”正常地“呼吸”。每年的夏天都要对图书在阴凉、干燥、通风处进行一次晾晒,是最好的防热措施。
六忌压。一本书受压过大,书页间空气无法流通,页与页之间就易粘连。解决这一问题的的办法是常翻动,不要使一本书长年累月地处在最低层。书与书之间不可挤压过紧,上下左右以能随时随处取出该书为宜。否则会出现书脊泛黄,与书籍封面内容颜色不一致的“难看”情形。这些对于爱书如命的人,是最痛心疾首的啦。

控制流: 在本章我们只介绍了if控制和for,但是没有提到switch多路选择。这里是一个简单的switch的例子:

switch coinflip() {
case "heads":
    heads++
case "tails":
    tails++
default:
    fmt.Println("landed on edge!")
}

在翻转硬币的时候,例子里的coinflip函数返回几种不同的结果,每一个case都会对应一个返回结果,这里需要注意,Go语言并不需要显式地在每一个case后写break,语言默认执行完case后的逻辑语句会自动退出。当然了,如果你想要相邻的几个case都执行同一逻辑的话,需要自己显式地写上一个fallthrough语句来覆盖这种默认行为。不过fallthrough语句在一般的程序中很少用到。
Go语言里的switch还可以不带操作对象(译注:switch不带操作对象时默认用true值代替,然后将每个case的表达式和true值进行比较);可以直接罗列多种条件,像其它语言里面的多个if else一样,下面是一个例子:

func Signum(x int) int {
    switch {
    case x > 0:
        return +1
    default:
        return 0
    case x < 0:
        return -1
    }
}

这种形式叫做无tag switch(tagless switch);这和switch true是等价的。
像for和if控制语句一样,switch也可以紧跟一个简短的变量声明,一个自增表达式、赋值语句,或者一个函数调用(译注:比其它语言丰富)。
break和continue语句会改变控制流。和其它语言中的break和continue一样,break会中断当前的循环,并开始执行循环之后的内容,而continue会跳过当前循环,并开始执行下一次循环。这两个语句除了可以控制for循环,还可以用来控制switch和select语句(之后会讲到),在1.3节中我们看到,continue会跳过内层的循环,如果我们想跳过的是更外层的循环的话,我们可以在相应的位置加上label,这样break和continue就可以根据我们的想法来continue和break任意循环。这看起来甚至有点像goto语句的作用了。当然,一般程序员也不会用到这种操作。这两种行为更多地被用到机器生成的代码中。
命名类型: 类型声明使得我们可以很方便地给一个特殊类型一个名字。因为struct类型声明通常非常地长,所以我们总要给这种struct取一个名字。本章中就有这样一个例子,二维点类型:

type Point struct {
    X, Y int
}
var p Point

类型声明和命名类型会在第二章中介绍。
指针: Go语言提供了指针。指针是一种直接存储了变量的内存地址的数据类型。在其它语言中,比如C语言,指针操作是完全不受约束的。在另外一些语言中,指针一般被处理为“引用”,除了到处传递这些指针之外,并不能对这些指针做太多事情。Go语言在这两种范围中取了一种平衡。指针是可见的内存地址,&操作符可以返回一个变量的内存地址,并且*操作符可以获取指针指向的变量内容,但是在Go语言里没有指针运算,也就是不能像c语言里可以对指针进行加或减操作。我们会在2.3.2中进行详细介绍。
方法和接口: 方法是和命名类型关联的一类函数。Go语言里比较特殊的是方法可以被关联到任意一种命名类型。在第六章我们会详细地讲方法。接口是一种抽象类型,这种类型可以让我们以同样的方式来处理不同的固有类型,不用关心它们的具体实现,而只需要关注它们提供的方法。第七章中会详细说明这些内容。
包(packages): Go语言提供了一些很好用的package,并且这些package是可以扩展的。Go语言社区已经创造并且分享了很多很多。所以Go语言编程大多数情况下就是用已有的package来写我们自己的代码。通过这本书,我们会讲解一些重要的标准库内的package,但是还是有很多限于篇幅没有去说明,因为我们没法在这样的厚度的书里去做一部代码大全。
在你开始写一个新程序之前,最好先去检查一下是不是已经有了现成的库可以帮助你更高效地完成这件事情。你可以在 https://golang.org/pkghttps://godoc.org中找到标准库和社区写的package。godoc这个工具可以让你直接在本地命令行阅读标准库的文档。比如下面这个例子。

$ go doc http.ListenAndServe
package http // import "net/http"
func ListenAndServe(addr string, handler Handler) error
    ListenAndServe listens on the TCP network address addr and then
    calls Serve with handler to handle requests on incoming connections.
...

注释: 我们之前已经提到过了在源文件的开头写的注释是这个源文件的文档。在每一个函数之前写一个说明函数行为的注释也是一个好习惯。这些惯例很重要,因为这些内容会被像godoc这样的工具检测到,并且在执行命令时显示这些注释。具体可以参考10.7.4。
多行注释可以用 /* ... */ 来包裹,和其它大多数语言一样。在文件一开头的注释一般都是这种形式,或者一大段的解释性的注释文字也会被这符号包住,来避免每一行都需要加//。在注释中//和/*是没什么意义的,所以不要在注释中再嵌入注释。

报错 expected 'IDENT', found 'go'

运行go run
文件目录为

.
├── README.md
├── fetch
│   ├── fetch.go
│   ├── fetch1.7.go
│   ├── fetchall.go
│   ├── server1.go
│   ├── server2.go
│   └── server3.go
└── go-demo
    ├── main.go
    ├── mgif.go
    └── mutiFiles-package
        ├── main.go
        └── util.go

./go-demo/main.go

package go-demo
...

由于package 命名为go-demo,命名格式不规范,导致的这个问题。
解决办法:将go-demo 统一改为 gostart ,去掉 - 字符 报错解决。
反思:包的名字应只用小写。不要用下划线式,也不要用驼峰式。使用单数
参考: https://studygolang.com/articles/11823

<h4>为什么PHP中的变量前边要加'$'符号</h4>
一直都特别好奇 PHP 中的变量前边都加 $ 符号。别的大众编程语言从没见过这种设定,比如:java,c#,c,c++,go,Ruby,python 甚至连写法被吐槽最多的 Objective-c 都没有。那么这种设定是怎么来的?为什么要这样做呢。
OK,我的第一篇 IT考古文章就来研究探寻一下这个问题。
下面是我人肉过滤掉噪音信息后得到的回答:

历史问题,unix那时候就存在了,SHELL,PERL。。。等脚本语言都是那样定义变量的,主要是区分字符和变量。例如 echo test就是字符"test",echo $test就是输出变量的值。——by umbrella1984
1、加一个$可以使解释程序大为简化,从而提高运行速度
2、php出世的时候perl已经比较流行了,所以加一个$可以吸引众多的perl程序员转向
——by xuzuning
加了$,又可以多使用一些单词做为变量名,不受保留字的影响,变量命名更自由,并且解释器在文本中只要搜索到'$'就可以判断其为变量了。而不用像其他编译型语言那样,总是查找已定义的变量表来判断变量。
不过你说的那个在编辑器中变量名文本拷贝的问题确实挺麻烦,双击一个单词后,它是不会将'$'选中的。还是要手动筛选
——by Metal Lovers

最后奉上一种貌似靠谱,但是最扯最迷惑人的解释

网友1:
!     表示“非”被用到判断中了if(!isset...)
@   被用到防止SQL输出错误信息了
#    常用的注释符号,UNIX系统下#有它的重大意思
%   被用作SQL模糊匹配和ASP程序
^     被用作正则中了
&    就更不用说了,被表示成and($a &amp;&amp; $b)
     这个符号更不能用了,还记得SQL语句中的SELECT  吗?
()   也是不合理的,要不然你得判断语句还怎么写
-+ 这属于运算符号,也不能用
';   之类的就更别提了。。。
你看看,PHP除了用$符号还有什么好的选择?
——by https://blog.csdn.net/ITofwanyifei/article/details/40450553

<h4>PHP的产生历史</h4>
PHP 最初是1994年Rasmus Lerdorf创建的,刚刚开始只是一个简单的用Perl语言编写的程序,用来统计他自己网站的访问者。后来又用C语言重新编写,包括可以访问数据库。在1995年以Personal Home Page Tools (PHP Tools) 开始对外发表第一个版本,Lerdorf写了一些介绍此程序的文档,并且发布了PHP1.0。在这早期的版本中,提供了访客留言本、访客计数器等简单的功能。以后越来越多的网站使用了PHP,并且强烈要且增加一些特性,比如循环语句和数组变量等等,在新的成员加入开发行列之后,在1995年中,PHP2.0发布了。第二版定名为PHP/FI(Form Interpreter)。PHP/FI加入了对mSQL的支持,从此建立了PHP在动态网页开发上的地位。
注意 这里明确指出,PHP最开始是用 Perl 编写的程序。这就是 PHP 天生的基因。而 Perl 语言里面的变量就是用 $ 表明的。
参考PHP的历史
<h4>所以总结</h4>
PHP 是由 Perl 进化而来的。而那个年代,所有的 类Unix 脚本语言都是前边添加$这样定义变量的,为的是区分字符和变量。
至于后边的便于解释器优化,容易使程序员一眼看到那些是变量,变量起名更自由,等等解释。都是以后的事儿了。大家做阅读理解嘛,请解释一下作者写这段话的心理活动,类似这种的。

Go 的底层语言是什么

借用大神的话来说

编译器就是输入源代码输出其他语言源代码的程序

所以这个程序用什么语言实现无所谓
然而,一开始没有go,所以用c实现了一版go编译器,后来go语言存在了,那就可以用go再重写一遍编译器,用c写的编译器来编译这个新的编译器的源代码
然后就成了现在这个样子
你可以找找老版本看看c实现

2015年8月19日,Go语言Go 1.5版发布,本次更新中移除了”最后残余的C代码”

从此 Go 实现了自举

Go 的市场定位

Go语言尤其适合编写网络服务相关基础设施,同时也适合开发一些工具软件和系统软件。
​ ——《The Go Programming Language》
Go 语言能吞食的一定是 PaaS 上的项目,比如一些消息缓存中间件、服务发现、服务代理、控制系统、Agent、日志收集等等,没有复杂的业务场景,也到不了特别底层(如操作系统)的中间平台层的软件项目或工具。而 C 和 C++ 会被打到更底层,Java 会被打到更上层的业务层。这是左耳朵耗子的一个判断。
用上面的标尺来量一下 Go 语言的杀手级应用 Docker,你会发现基本是一样的。
学习文档