go and php

运行与编译


PHP是解释型语言,构建在ZEND虚拟机上,运行时首先会被zend引擎编译或者解释为OPCODE(或者运行时读取已经缓存的OPCODE),再由zend引擎处理后对接机器指令。
所以PHP现在作为web语言有一个明显的优势,代码更新后没有重启的概念,下次执行的时候直接读取新文件解释。

Go 是编译型语言,运行前需要直接编译为机器指令的二进制可执行文件。
所以一些数据结构造成的问题是可以在编译时检查出来的,当然调用值超下标之类的就没办法了。
最大的问题是每次代码更新后都需要重新编译,作为web服务支持需要停止原来的服务重启新的服务,至少我还没想到好的解决方案。好在Go的编译启动很快,现在看是毫秒级的。

语言类型


PHP是绝对的弱类型语言
PHP里几乎没有类型的概念,int和string bool可以默认转换,一个数组可以有任何类型的数据结构。或者我可以理解为没有数据结构的概念,因为会在编译为OPCODE的时候根据词法分析、语法分析、语义分析和优化最终生成对应机器语言。

Go是强类型语言
Go里的数据结构要求非常严格。不同位的int都只能强制转换。slice和数组只能包含同一类型的数据结构,在定义时基本就要指定(或者在赋值时默认定义)。要想像PHP那样一个返回一个包含各种数据结构的数组型数据,只能定义一个结构体struct。其实PHP的数组可以理解是伪数组吧,就可以理解为结构体。

web服务


PHP本身没有web服务的概念,虽然它就是为了web而生的。它只能对接第三方web服务(Apache Nginx)。
这其实也切合互联网发展历程的吧。最早的互联网是静态的,只需要web服务即可。后面随着发展肯定没法接受纯静态互联网,于是就有了动态的需求,但是web服务器自身是不能支持动态的,怎么办呢,记得以前看过印象深刻的话,在计算机领域,没有什么是加一个中间件解决不了的。CGI出现了,通用网关接口,也可以理解为一个对接web服务的规范吧,只要动态语言支持这个规范就可以接上web服务器了,PHP的诞生应该是伴随着fastcgi的吧,经常看到进程里有一个php-cgi,就是这玩意吧,当然后面因为单纯fastcgi的性能可能实在弱到没法忍受,就接着诞生了php-fpm,fastcgi process manager(以前老觉得这种fpm什么的专业术语吊炸天的样子,后来发现基本都是英文首字母的组合,就略无语)。当然fpm怎么提高性能就扯远了,也扯不出来,因为我也不太懂,总结就是一句话,PHP自己不支持web服务,靠CGI对接web服务器。

Go不需要第三方web服务器,它自己就可以支持web服务。Go的net包提供了各种接口,包括TCP/IP,UDP或者Unix下的socket。基于此,还开发出了专门针对的http的包。为了兼容现在的系统,还有http还有CGI和fcgi子包,具体干嘛的我也不知道。

垃圾回收机制


PHP的垃圾回收是靠引用计数,一个变量生成的时候自带计数,有人指向它计数就加一,所以指向它的都被unset掉了,计数变零,OK,这个内存可以释放掉了。我以前觉得PHP每个进程过来的时候生成一个新进程,然后请求结束干掉进程,那进程包含的内存肯定就自动释放掉了,但写着写着突然想到PHP是不是没有这么low每次请求是一个进程而不是一个线程,线程结束那进程还是有必须要主动释放指定的内存的吧,当然每个线程也有自己的标示,所以线程结束进程可以主动释放这个标示下的所以内存块吧。至于释放是不是靠引用计数就不知道了。反正这个请求结束相关的内存块都被干掉了是肯定的。所以PHPer不用考虑内存释放不释放的,反正请求结束全自动释放。

Go的垃圾回收是不可达回收,就是一个变量在运行的过程中发现后面用不到它了,OK,放到回收池,等到一定量了一起回收掉。这个回收的过程会STW(stop the world,还是那个奇葩怪癖),所以饱受诟病。太较真了,要是这样谁都写不出来纯完美的代码吧。

开发

1 引用代码
golang使用包的概念引用代码可以方便的让代码独立出来,一个脚本只需要import所需的脚本就行了,显得更为简洁容易。
PHP经过长时间的发展,基本都是框架式使用,如果要单独的开发一个小项目或者脚本比较麻烦,需要把部分代码拷贝来拷贝去。

其他

代码最后不要分好,引用服务调用包等其余部分感觉具体也写不出来什么,而且Go确实也还不太熟悉。先写这么多,以后想到再说吧