图片服务器的Nodejs和Go版本性能测试

关于上一版本

  昨天完成了nodejs版本的图片服务器staticserv
之后,当时没有对请求的类型做判断,这只是我自己使用,如果是做成通用模块,需要考虑防范不合适的请求。之前,
首先考虑的是Go版本的服务器,只不过自己没有弄清go的资源地址都是相对于项目的GOPATH的地址,还是使用老方法
\a\b\c.txt去读取文件,结果都无法读到文件,所以写了nodejs版本。今天学习了path/filepath模块之后,终于掌握
了正确写法。比如要读取”./a/b.txt”,需要这么写:

1
2
absPath:_:=filepath.Abs("./a/b.txt")
bytes,err:=ioutil.ReadFile(absPath)

Go版本的主要功能

  1. 自定义资源文件位置
    主要是通过flag模块解析src参数来实现,比如
    1
    2
    3
    4
    5
    ./serv -src /tmp
    请求URL:
    http://xxx/123.jpg
    最终服务器查找的文件地址:
    /tmp/123.jpg

测试中对于”//“这种错误也能兼容,因为它使用的是Join转化路径,而不是拼接字符串。
关键代码如下:

1
2
relativePath := req.URL.Path
filename, err := filepath.Abs(filepath.Join(*curDir, relativePath))

  1. 判断请求类型
    这部分主要有忽略”favicon.ico”请求、判断路径是否正确和文件是否存在
    1
    2
    3
    4
    //忽略favicon请求:
    if relativePath == "/favicon.ico" {
    return
    }

路径是否正确直接判断上文中的err就好了,这里就不表述。实验时发现请求的是目录,服务
器立马输出错误,然后退出了。这怎么行,一点都不健壮,所以要判断是不是文件:

1
2
3
4
5
6
7
8
9
10
11
12
fileinfo, e := os.Stat(filename)
//文件不存在
if os.IsNotExist(e) {
log.Println(filename, " is not exists.")
res.WriteHeader(404)
return
}
//不是文件,返回500错误
if fileinfo.IsDir() {
res.WriteHeader(500)
return
}

  1. 判断文件类型并读取、发送文据
    判断文件类型主要是为了响应时的content-type,对于不是图片的请求,直接返回了text/plain:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    extname := filepath.Ext(reqfile)
    switch extname {
    case ".jpg", ".jpeg", ".jpe", ".jfif":
    return "image/jpeg"
    case ".png":
    return "image/png"
    case ".ico":
    return "image/x-icon"
    case ".gif":
    return "image/gif"
    case ".tif", ".tiff":
    return "image/jiff"
    default:
    return "text/plain"
    }

发送数据就比较简单了,为了不在传递参数时拷贝,我用了拷贝指针的办法:

1
2
3
4
5
var data []byte
//读取文件
ReadFileFromPath(&data, filename)
res.WriteHeader(200)
res.Write(data)

与上一版本的性能测试对比

这里主要用到了apache的ab工具,以及开源软件webbench。
两者都在同一环境下,均没有做优化。

  1. ab测试,并发请求200,总请求数4000:
    1
    ab -c 200 -n 4000 http://localhost:8080/fact10000.png

测试结果如下:

go 版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

Document Path: /img/fact10000.png
Document Length: 27488 bytes

Concurrency Level: 200
Time taken for tests: 2.493 seconds
Complete requests: 4000
Failed requests: 0
Total transferred: 110276000 bytes
HTML transferred: 109952000 bytes
Requests per second: 1604.80 [#/sec] (mean)
Time per request: 124.626 [ms] (mean)
Time per request: 0.623 [ms] (mean, across all concurrent requests)
Transfer rate: 43205.78 [Kbytes/sec] received //网络传输速度,排除网路问题

/*网络上消耗的时间的分解*/
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 4 39.6 0 1003
Processing: 3 117 143.3 56 1184
Waiting: 2 65 41.9 50 173
Total: 4 121 147.3 57 1184

*下面的内容为整个场景中所有请求的响应情况。在场景中每个请求都有一个响应时间,
其中 50% 的用户响应时间小于 57 毫秒,66 % 的用户响应时间小于 100 毫秒,
最大的响应时间小于 1184 毫秒*/

Percentage of the requests served within a certain time (ms)
50% 57
66% 109
75% 150
80% 157
90% 290
95% 406
98% 583
99% 739
100% 1184 (longest request)

nodejs版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Concurrency Level:      200
Time taken for tests: 3.019 seconds
Complete requests: 4000
Failed requests: 0
Total transferred: 110352000 bytes
HTML transferred: 109952000 bytes
Requests per second: 1325.07 [#/sec] (mean)
Time per request: 150.935 [ms] (mean)
Time per request: 0.755 [ms] (mean, across all concurrent requests)
Transfer rate: 35699.34 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 24 150.8 0 1003
Processing: 67 119 50.4 103 420
Waiting: 67 118 50.3 103 420
Total: 71 143 156.3 105 1116

Percentage of the requests served within a certain time (ms)
50% 105
66% 125
75% 141
80% 145
90% 160
95% 303
98% 1093
99% 1099
100% 1116 (longest request)

二者情况是差不多的,go略微好于nodejs。

  1. 连续3次请求测试平均值,选取用户最关心的三项参数
    go:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Requests per second:    1604.80 [#/sec] (mean)    //吞吐率
    Time per request: 124.626 [ms] (mean) //用户平均请求等待时间
    Time per request: 0.623 [ms] (mean, across all concurrent requests) //服务器平均请求等待时间

    Requests per second: 1627.66 [#/sec] (mean)
    Time per request: 122.876 [ms] (mean)
    Time per request: 0.614 [ms] (mean, across all concurrent requests)

    Requests per second: 1747.35 [#/sec] (mean)
    Time per request: 114.459 [ms] (mean)
    Time per request: 0.572 [ms] (mean, across all concurrent requests)

nodejs:

1
2
3
4
5
6
7
8
9
10
11
Requests per second:    1325.07 [#/sec] (mean)      
Time per request: 150.935 [ms] (mean)
Time per request: 0.755 [ms] (mean, across all concurrent requests)

Requests per second: 1156.69 [#/sec] (mean)
Time per request: 172.908 [ms] (mean)
Time per request: 0.865 [ms] (mean, across all concurrent requests)

Requests per second: 1231.65 [#/sec] (mean)
Time per request: 162.383 [ms] (mean)
Time per request: 0.812 [ms] (mean, across all concurrent requests)

可以看出二者在吞吐率上,Go好于nodejs,平均等待时间上二者相差无几。

  1. webbench 压力测试
    压力测试30秒内,并发请求数200,连续测试3次
    1
    webbench -t 30 -c 200 http://127.0.0.1:8080/img/fact10000.png

go的表现:

1
2
3
4
5
6
7
8
9
Speed=111574 pages/min, 51317124 bytes/sec. //速度,111574页/每分钟,51317124字节/秒
Speed=100538 pages/min, 46228920 bytes/sec.
Speed=103186 pages/min, 47440784 bytes/sec.

资源占用:
VIRT RES SHR CPU MEM TIME
364756 26252 4336 S 61.9 0.0 0:15.26 serv
364884 25960 4044 S 58.7 0.0
364884 25960 4044 R 57.9 0.0

nodejs的表现:

1
2
3
4
5
6
7
8
9
Speed=78864 pages/min, 36259112 bytes/sec.
Speed=42868 pages/min, 19710708 bytes/sec.
Speed=36340 pages/min, 16708262 bytes/sec.

资源占用:
VIRT RES SHR CPU MEM TIME
955320 74196 14252 R 73.6 0.1 0:10.49 node
960768 79408 14252 R 33.2 0.1
961604 79256 14252 R 34.7 0.1

二者都是0错误,可以看出nodejs在速度和资源占用率都比Go表现的差,
速度大概只有go的一半不到,内存占用率却是go的3倍左右,CPU使用率
稍好于go。

总结

从测试里可以看到,Go的http性能是好于nodejs的,不过对于这么
简单的应用,可能无法完全反应Go和nodejs的http性能高低吧,但是go的
http的模块我觉得很好用,写代码也是同步方式,不像nodejs我写到逻辑越来
越复杂的时候就有点越发要好好学一学异步编程的思想,这种思维转换一时还
无法适应,所以我往往选择javascript先完成一部分功能,打开思路后使用Go
去实现。
 另外今天的收获就是学会了做网络测试了,这对我来说又增长了能力。

静态文件服务

为什么做静态文件服务器

  这几天博客搭建起来后,美化和主题也设置得差不多了,就是在写作时,
有时候需要插入图片,图片使用的相对地址会在hexo生成博客时失效,总不
可能插入一个图片就在它生成后去相应的html里改引用地址吧,再说上传的时
候Hexo可能默认不会上传。
  所以这种情况下,就需要一个文件服务器去为我们生成的博客传输图片。

现有的解决方法

1.七牛服务

  七牛的静态文件服务听说性能很高,也是用我最近学习的golang写的。不少
人都是推荐这种服务,所以我就去七牛官网看了一下,有免费试用版,每个月
请求一万次到十万次,对我来说够用了。想注册的时候有以下两点要求我比较介意:

  • 需要填写手机号
  • 个人信息等隐私内容。

  国内的服务很多都把个人信息卖了,导致我总是收到垃圾短信和推销电话,因此现在就奉行
能不注册就不注册的态度。另外,我写个博客还要去七牛上上传,两边还得对上号,再说自己的
需求就是插入静态内容,也不复杂,为什么不自己做呢?自己动手,丰衣足食,还可以后续改进。
所以有了下面的做法。

2.在云上搭建文件服务器

  当浏览到包含插入图片的博客时,相当于发起了一次http请求,如果返回的是200,那就是说明
取到了图片,所以我们文件服务这边就是写一个http服务,监听这些请求,发送图片的数据过去就
行了。具体逻辑如下:

  1. 在md引用地址写上要请求的文件的地址A
  2. 服务监听端口,一旦有请求过来,就取request的url中的文件路径
  3. 判断该文件是否存在,如果不存在返回404
  4. 存在该文件的话,读取文件,response返回二进制数据即可

具体实现

  本来先写Go版本的,结果测试时,go中读取文件的”ioutil”和”os”模块都不能读取多层目录下的
文件内容,为了尽快上线,我用了nodejs,里面的http模块也很好用,异步不需要等待的特点正好适合
I/O操作,前期也没有考虑多个请求就开多个操作,或者是否Javascript异步模型不需要这些东西来提
高性能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var http = require('http');
var fs = require('fs');
var url = require('url');
var path = require('path');

/**
* 访问根目录在当前目录,
* 例如要访问img下的fact.png,就使用http://[云地址]:8080/img/fact.png
*
**/

http.createServer(function(req,res){
var rootPath = ".";
//屏蔽favicon请求
if(req.url!=='/favicon.ico'){
var filename = rootPath+req.url;
var img_type = path.extname(req.url).split('.')[1];
//读取相应的文件
fs.readFile(filename,'binary',function(err,file){
if(err){
res.writeHead(500,{"Content-Type":"text/plain"});
res.write(err+'\n');
console.log('request:',req.url,'\t\t[Failed].');
res.end();
}else{//返回数据
res.writeHead(200,{"Content-Type":"image/"+img_type});
res.write(file,"binary");
console.log('request:',req.url,'\t\t[Ok].');
res.end();//等待发送完成
}
});
}
}).listen(8080);

  然后将这段代码发在云上运行,并将博客里要插入的图片放在rootPath下,更新
博客后,再访问服务端果然出现了request ok的信息,gitcafe和github上的博客在浏
览时,也成功加载了图片。说明我的想法是正确的。

后续

服务器写的还是很简陋的,总的来说有以下需要改进:

  1. 将服务器地址写到配置文件中,而不是每次都写域名,更新域名更方便。
  2. 既没有对请求进行判断,不能防范攻击。
  3. 多个人浏览时是否依旧能流畅加载图片没有测试。
  4. javascript的异步模式应该多个请求怎么处理没有弄清。
      
    所以,接下来针对这几点,可以一边用一边改,这就是未完的工作了。不过好歹可以用了,
    也不用去注册一个服务,自己又得到了锻炼。说不定发展到最后可以提供多个服务。一个
    web框架大概也是这样一点一点地加起来的。

最近及假期之间的个人计划

最近的状况

  学校的报告一个接一个,等一个个忙完想休息一下,结果导师说我之前给他的报告不行,
不是要搜集论文,而是要找美国的存储实验室。1个月10到20个,还要有介绍,这就必须
要搜到实验室之后仔细看别人的实验室情况,有点大海捞针的意思。每天一来实验室面对
这些,春节过后还要找实习,必须要复习一些东西,另外之前的计划工作也需要完成,心态
就越发变得急躁了。
  从15年12月初开始就忙碌了起来,当时要考数学和英语,另外还有学院的一个项目,写报告,
复习,确定每天的工作计划,感觉事情就像流水线一样过来,必须要确定轻重缓急,看过很多书籍
和电影说把每天的工作列成一个清单,按重要程度分为20%和80%,完成那20%重要的事情。这样
才是有效率,不会忙了一天还不知道忙的什么。当时就觉得这个方案很有必要,开始每天在桌面上
写清单了,做完一个标记完成。可是时间一长,桌面图标多得惨不忍睹,也不知道具体一项任务写到
哪里去了,还是有点乱糟糟的。所以萌生了统一写博客里,还能不随时携带就可以查阅。

之前的清单

  • 工程数学 2015-12-05 完成(js 统计库一半)
  • 英语口语 2015-12-17 口语提纲 完成
  • 移动互联网演讲 2015-12-23 sslstrip实验 完成
  • 移动互联网安全报告 2016-01-03 完成
  • 并行处理报告 Latex 2016-01-05 LaTeX模板 完成
  • cdstore搭建、测试 2015-12-25 docker 完成

未来要做的事情

1.学业方面

准备:

  • Linux C底层,数据存储书籍,论文
  • 分散加密论文,Hash、前后相关论文
  • 数据去重论文

截止日期:2016-01-30 :待定

  • 实验室报告,至少15个,数量为先,介绍可以简单一些,只列出名称、网址、研究方向、研究成果
  • 磁盘分散加密,去重
    • C底层数据块控制
    • hash加密
    • 比对,删除重复,软连接保持一致
  • Latex学习,考虑写开题报告

2.工作相关

时间:2016-01-10 ~ 2016-03

  • 数据结构复习,链表、优先队列、二叉树、哈希表相关,c/go实现
  • 操作系统,线程相关,了解分布式
  • 网络,http/net相关,TCP/IP介绍,epoll,Ajax异步
  • 数据库,完整操作一遍
  • 相关复习计划参照2016工作后台准备

3.业余锻炼

起始:2016-02-01 ~ 2016-03

  • 博客文件服务器,根据请求返回插图
  • go数据结构与算法
  • beego博客,ajax前端部分

后记

  先想到这些,就暂时记这么多吧,完成一件会标记一项。按照事情紧迫性一件件地去落实,
相信最终必然有收获!

Hexo静态博客建立指南

静态博客搭建

  • 主要针对新版hexo(>=3.0),之前的也就是同时发布的修改方法不同

根据我这两天搭建的经历,写下详细的帮助教程,总结自己的经验,也是为了避免后来者犯错。
注意:现在hexo都是3.0以上版本,使用方法与之前的2.0版本有所不同,这也是我被坑的地方,需要用新的方法.

1.安装Hexo等工具

1
2
前提工具:git nodejs npm ssh服务
npm install hexo hexo-deploy-git -g

我安装在免费的云中,这样换个地方,换台电脑也能有环境编辑上传文件,安装在本地需要额外的步骤。
国内免费的有代码市场,反正也就一个编辑上传的地方。当然也可以直接使用
云的服务建立博客,这种最简单。

2.建立本地镜像

1
2
3
mkdir <your project>             //博客项目文件夹
cd <your project> && hexo init //进入项目,初始化hexo环境
npm install //安装必要组件

此时就可以新建博客了

3.创建博客

1
2
hexo new page '<blog title>'     //会在/source/_posts/生成相应的文件文件夹
编辑index.md即可

或者直接发布到_post:

1
hexo new <blog name>

4.发布方法

1.发布在云上

1
hexo g && hexo s               //生成博客,并开始启动服务

此时访问云分配给你的http://域名:4000/即可看到你的博客

2.发布在Github

  1. 在自己的github上建立一个与用户名相同的repo
  2. 在repo Settings中选择开启Github Pages
  3. 由于之前安装了hexo-deploy-git,因此只要配置git config即可

    1
    2
    git config --global user.name "your github name"
    git config --global user.email "you github email"
  4. 修改本地站点下的/_config.xml,找到deploy:

    1
    2
    3
    4
    5
    deploy:
    type: git
    message: "update blog."
    repo:
    github: git@github.com:your-name/youn-name.github.io.git

注意:这里不是网上所说的那种配置方式:

1
2
3
4
deploy:
type: github
repo: git@github.com:luoyibu/luoyibu.github.io.git
branch: master

当然,这种方式也可以,不过一次发布到2个及以上的托管服务会有问题,所以还是
使用新方法吧!

  1. 发布博客
    1
    2
    3
    4
    5
    发布之前,最好清理本地环境:
    hexo clean

    生成并发布:
    hexo d -g //与 hexo g -d 相同

3.发布在Gitcafe

由于github在国外,国内访问不稳定,可以使用国内服务gitcafe,操作步骤也差不多。
这里提一下提前准备的东西。

  1. 最好使用和github同名的账户,我就是这么干的,这样全局git config就是一样的,省去
    一些麻烦。然后新建一个同用户名的repo
  2. 在~/.ssh下生成ssh密钥:

    1
    ssh-keygen -t rsa -C "邮箱地址"
  3. copy id_rsa.pub中内容到github和gitcafe SSH 公钥管理中

  4. 修改本地站点下的/_config.xml,找到deploy:
    1
    2
    3
    4
    5
    deploy:
    type: git
    message: "update blog."
    repo:
    gitcafe: git@gitcafe.com:your-name/your-name.git

这里和网上教程介绍的也不一样,不需要brach: gitcafe-pages也能成功。
之后发布操作和github发布相同,就不再赘述。

Github和Gitcafe同时发布

github访问不稳定,gitcafe又快,为了国际化,能不能两个都发布呢?相信很多人和我
的想法一样,我找了很多资料,就连写makefile的都有,现在新版,同时发布已经很方便了。
网上大部分的是:

1
2
3
4
5
6
7
8
修改本地站点下的*/_config.xml*,修改*deploy*:

deploy:
type: git
message: [message]
repo:
github: <repository url>,master
gitcafe: <repository url>,gitcafe-pages

这种在新版中经过我测试是不行的,github 的master分支一直出错,只有gitcage能成功。

新版方法

1
2
3
4
5
6
deploy:
type: git
message: "update blog."
repo:
github: git@github.com:your-name/your-name.github.io.git
gitcafe: git@gitcafe.com:your-name/your-name.git

不需要设置brach,两个发布都会成功。


5.其他有用的操作

改变博客的主题颜色

  • 由于使用的主题惨白的,对我来说是比较难看清内容的,所以我开始折腾
    怎么换主题,去看原作者,发现他语焉不详,只提了一下solarized dark和highlightjs
    高亮。然后昨晚对比css忙活到大半夜也没有成功。
  • 今天仔细搜了下发现hexo3以上版本用的就是highlightjs,并且node_modules里已经有
    stylus插件了,所以尝试了在theme中的config定义theme_color为常用sublime配色,果然成功了!

现在记录下来以帮助那些还在惨白主题中苦苦挣扎的程序员吧!

  • 可以去highlightjs官网的demo选择自己喜欢的主题
  • /_config.yml添加:
    1
    2
    theme_color:
    theme: "Monokai Sublime" //你的主题名字

重新部署博客就可以看到新主题生效了,再也不用盯着惨白色看博客。

博客删除

1
2
3
4
5
6
7
删除仓库里面 source/_posts/我的文章.md

执行下面命令更新博客

hexo g == hexo generate#生成
hexo s == hexo server #启动服务预览
hexo d == hexo deploy#部署

添加分类/tags

新建分类:

1
hexo new page "<category name>"

在生成的相应md中修改如下:

1
2
3
title: <文章标题>
date: 2016-01-09 10:56:27
type: "<category name>"

修改本地layour下的/themes//_config.xml,找到menu:

1
2
3
4
menu:
main: /
archives: /archives
category: /<category name>

新建tags

直接在新建的md文件中添加

1
tags: <your tag name>

修改本地layour下的/themes//_config.xml,添加:

1
tags: /<your tag name>

改变新建博客的模板

修改/scaffolds/下相应的文件即可:

1
2
post.md  ==>  对应hexo new 生成的md模板
page.md ==> 对应hexo new page生成的categories模板

可以在其中加上categories:模板,这样就不用每次手动添加了。
例如:

1
2
3
4
title: {{ title }}
author: {{ your-name }} //添加的模板
date: {{ date }}
tags:

最后

  今天通过这种方法,我在githubgitcafe上的博客
都正常运行了,也是经经历一番排错和查找问题的经历。
  其实有些东西自己摸索出来还是很有成就感的,印象也更深,即使是别人早已知道的。
希望给想建立自己博客的人一点帮助。后续遇到的一些问题都会在博客上更新,
欢迎关注!

关于合适语言的一点看法

语言之争

每当一种语言诞生,世界上的争吵就多了一种声音。经常可见这样的讨论:

1
2
3
4
"xxx就不错,yyy是垃圾,这都不支持!"
"xxx太复杂了,不适合如今的应用模式。"
"xxx是最好的语言。"
....

我大学期间也自学很多语言,主要是想做个东西出来,看别人推荐什么语言,有什么现成的库,
就开始了入坑之旅。

  • 从那以后,我就开始用python写爬虫抓音乐链接,书籍,还写了一些获取ss节点的程序,运行更新节点信息,
    就可以很方便上外网了。感兴趣的可以移步我的github:ss-config-graber,
    xcode文档的真实下载地址:XcodeDocDownload
  • Java写过界面游戏,当时的数值算法这门课我都是用它完成作业,还有被写烂了的xxx管理系统,也正是Java,让我
    开始使用数据库而不是用写文件读文件的方式。
  • c/c++写算法,数据结构,做OJ。往往一遍又一遍的去优化,看着用时又减少了就很开心。
  • 后来Javascript居然可以写服务器端的应用,特别是express路由、模板、控制器简洁明了,路由注册拦截请求,调用中间件
    处理数据,控制器控制由模型组成的数据去渲染模板。一个web系统就这样做完了,效率很高,所以当时写写回调也无所谓,还顺便
    学习了前段的Ajax操作,那种处理和表现数据的感觉现在都印象深刻。所以正在上的工程数学的矩阵分解和一些统计方法我都想
    办法写成js程序,放在手机里直接用。真的是到处运行。
  • 学了golang后

学习完这些主流语言的感受

  • Java写得冗长,框架笨重又得配置xml,但是一旦项目规模上来了,
    它却是协作下表现最不差的解决方案。因此现在使用Java最广泛。
    毕竟水平一般不知道控制代码质量和内存使用的人太多。

  • C没有类型系统,我看过一些为C添加的对象系统,使用宏如同魔法
    一样,但是这种法案离C写基础构件的初衷还是很远,不是经历过正规
    训练的人很难习惯和掌握什么都需要自己创造的环境。另外C的字符串
    处理太弱,由于历史原因不支持UTF-8,这就在今天大部分的字符串处理
    逻辑里带来不便。

  • C++在C的基础上添加了很多语法,字符串处理同样比较差,多种范式,
    怎么写都有办法达到目的,写起来最不容易控制复杂性,或者是在中途为
    了追求优雅高效而忘记了自己究竟要干什么。项目不是写到一半被抛弃,
    或者重构的时候干脆从头开始造轮子了。

  • 还有重要的一点是,C++的Bug最难找,由内存处置不当导致的错误层出
    不穷,如果使用了高级特性如模板、迭代器、算子之后一旦出错错误信息
    如果天书一样在屏幕上滚过,而你的一天就这样过去了。

  • 我见过很多C++的拥趸说C++是最强的语言,什么都能做还能做得很好,
    这点确实如此,但是这么一件强大的武器需要非常熟练它的人才能发挥出它
    的功效,而不是写过只有几百行代码就莫名喜欢的人所认为的那样,也不是
    指针不释放,内存到处申请的人就能自称熟练使用C++。

  • python写出的程序直观,最适合初期快速实现自己的想法。但是多线程GIL
    的原因,重构社么的也麻烦,因为写的时候太自由了,同样不能充当主力,
    而是作为干杂活的最佳选择,写出1.0版最快。

  • javascript异军突起,google的V8引擎功不可没,现在进本上基本上所有智
    能设备都可以支持javascript,这就有了广泛的市场。但是它的异步特性使得
    我们长期受到一步一步操作的思路影响的大脑有点难以接受,常常困惑于为什
    么没有取到数据,那一层层的函数包裹搞得人连函数边界在哪都不知道。这就
    限制了一般程序员的使用,对象和继承出现的问题也比较奇怪。总的来说在web
    前后端还是不错的,一致的语言带来的是连贯的思路,思路清晰又往往可以保
    证项目完工,半路失败的项目太多了。

  • PHP也略微了解一些,在web领域也是非Java就PHP了,简单易于掌握的才是最
    好的,不管是个人开发者还是团队来说。最近准备了解Laravel框架,思路和
    express一样,也是路由、控制器、模型,避免了之前写php的随心所欲,就像写
    网页的php里面有连接数据库。其他领域基本就没有phph用武之地了。

  • golang语言2007才出现,其特点是足够简单,还有很好的一点是静态编译,没有
    依赖问题。我之前认为动态编译的程序,内存中只有一份,节省内存,程度加载的也快,
    静态编译不好,慢不说程序占用空间还大。但是今天IT行业已经变了,到处都是云环境,
    CPU、内存、硬盘太多了,反而生产环境变得复杂了,一不小心某个依赖变了,应用就有
    可能出问题,静态编译却没有这个主要困扰开发者的问题。用下来感觉挺不错的。缺点是
    没有泛型,写通用操作不方便,传个interface{}感觉怪怪的,它的特色goroutine我用的
    还不是很多,国内使用的案例也比较少,可能没有公开或者别人还在观望。也只有以后再
    补充自己使用的感受了。强制统一的规范比如大写方法可以导出,用习惯了自觉地在其他
    语言里也是用这种规范,而规范减少了出bug的可能。自带的测试命令也使得我写单元测试
    保证正确性,以前写代码就是弄一两个数据测一下就算完事,而这种单元测试经常能发现边
    界情况的错误,还有性能测试、代码覆盖度测试都可以保证代码是工程级而不是玩票性质。
    最近就在写golang的常用的数据结构和算法库,也算是轮子吧,可以关注utils
    获取最新进展。

总结

  由于我接触的东西还不是很复杂,所以自己的这些看法难免会有一些错误的地方,之后随着阅
历的增加,感受自然会多起来。随着代码量的增长,我越来越觉得每种语言都有适合运用的场
景和劣势的地方,并不存在统一的万能解决方案,也不是以个人情绪来判断好坏。
  我倾向的一种工作方式是,先用动态语言快速实现自己最重要的目标,之后可以将关键部分慢
慢升级换成Java这样的工业成熟方案,性能要求高的地方c/c++改写,让它们成为为应用提供服务的
组件。上层用户使用的地方javascript做初步操作,或者充当业务初步处理层。分布式的场景,
golang的通讯交换消息方式也有erlang先行者,性能非常出色。

,