[转] Go Slice 秘籍

Golang官方总结: Slice Tricks

由于引入了内建的append的方法, 包container/vector的很多方法都被移除,可以被内建的appendcopy方法代替。

下面是栈vector的操作方法的实现,使用slice实现相关的操作。

1. Append Vector

a = append(a, b...)

2. Copy

b = make([]T, len(a))
copy(b, a)
//如果a不为空, 等效实现
b = append([]T(nil), a...)

3. Cut

a = append(a[:i], a[j:]...)

4. Delete

a = append(a[:i], a[i + 1]...)
// 或者
a = a[:i + copy(a[i:], a[i + 1])]

5. Delete,而不保持原有顺序

a[i] = a[len(a) - 1]
a = a[:len(a) - 1]

注意:如果需要被GC回收的元素是一个指针,或者struct含有指针字段,上面的cut,delete实现可能就导致内存泄漏:一些元素的值会被a一直引用而不会被回收。下面的实现可以解决这个问题:

Cut

copy(a[i:], a[j:])
for k,n := len(a)-j+i, len(a); k<n; k++ {
  a[k] = nil
}
a = a[:len(a)-j+i]

Delete

copy(a[i:], a[i+1:])
a[len(a)-1] = nil
a = a[:len(a)-1]

Delete 而不保持原来的顺序

a[i] =a[len(a)-1]
a[len(a)-1]=nil
a = a[:len(a)-1]

6.Expand

a = append(a[:i], append(make([]T, j), a[i:]...)...)

7.Extend

a = append(a, make([]T, j)...)

8.Insert

a = append(a[:i], append([]T{x}, a[i:]...)...)

注意 : 第二个append使用自己的底层存储创建一个新的slice,然后复制a[:i]中的元素到这个slice中,然后再把这些元素复制回a。新slice的创建和第二次的复制通过另外一种方式避免:

2017-03-31    
SSL自签发

1、生成CA私钥

openssl genrsa -out ca.key 2048

2、私钥CA证书

openssl req -x509 -new -nodes -key ca.key -subj "/CN=xxx.com" -days 5000 -out ca.crt

3、生成服务私钥

openssl genrsa -out server.key 2048

4、服务私钥证书

#这里的/cn可以是必须添加的 是服务端的域名 或者是etc/hosts中的ip别名
openssl req -new -key server.key -subj "/CN=server" -out server.csr

5、对服务证书进行签发

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000

6、查询所生成证书的信息

openssl x509  -noout -text -in ./server.crt

7、生存Client端证书

openssl genrsa -out client.key 2048

openssl req -new -key client.key -subj "/CN=client" -out client.csr

echo extendedKeyUsage=clientAuth > extfile.conf

openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile extfile.conf -out client.crt -days 5000
2017-03-30    
React.js 使用小结(开篇)

React.js 使用小结—-序

生命不止,奋斗不息

最近三个月,参与了一个企业后台管理系统的小项目,采用前后端分离架构。前端实现技术选型时,选择了React.js。因为之前由大量使用WPF,也接触函数式编程(F#)的经历,所以第一次接触到React.js时就感觉非常的亲切。至少相对于AnglarJS而言,让我感觉更加的舒服。由于这个项目之前,没有项目中实际应用React.js的经验(其他队友也没有这方面的经验),工期也比较紧,选择React.js还是由比较大的风险,所以也促使在具体技术方案的选择上,更加务实了。

技术栈的选择

并且使用Antd Admin ,一个基于reactant-designdvaMock 企业级后台管理系统最佳实践,基于Mock可以实现脱离后端独立开发,基于dva动态加载Model和路由按需加载,浅度响应式设计。

这些技术可以很好的满足这个项目的需求,直达痛点。前后端同时开发、按需加载、响应式设计、前端UI,这些无疑都是我这个项目急需的特性。

实现过程的反思

后端开发,选定Spring Boot框架,来简化Spring应用的初始搭建以及开发过程;使用Maven进行包管理,来提供Restful API供前端使用。

由于是同时开发,原先预先定义的开发规则是: 后端的开发人员,先设计API接口,并使用Markdown编写API文档。前端根据API文档,使用Mock数据进行同步开发。通过这种方式来加快开发进度。

理想很丰满,现实真的很骨感。开发过程中,问题不断。由于开发流程上缺乏有力的管理和约束,导致出现较大偏差。

首先、后端开发,没有严格先设计API,而是先进行编码实现后,再来编写API文档。其次、部分队友抵触Markdown写文档,导致没有按照预先的格式编写,导致API文档即使写了,也很难阅读。最终的结果是,配合不顺,开发进度也没有预想的快。前端无法有效的沟通,后端开发人员浪费时间写了不可用和不及时的文档。前后端开发进度不一致,前端只能预设API来Mock数据,在最后联调时,出现大量接口不一致需要返工情形。此外,后端开发人员,开发出一个API接口后,没有做必要的测试工作,导致联调时,一个接口要反复几次,后端才能提供一个无误的接口。Bug的蔓延,导致影响不断扩大。

现在开来,还是对一般程序员先设计再编码的开发方式太乐观了,也许Swagger API 是目前现状的一个不错的解决办法。

此外,前后端,都没有引用测试用例,更别谈测试驱动开发(DDD)。大概上面的人,会认为项目太小没有必要,或是耽误开发进度的缘故。虽然测试驱动开发不是银弹,但也的确能解决一部分问题,重要的还是开发觉悟,即使不完全使用测试驱动开发,测试用例还是大有益处的,这个还是得加强影响。

使用的技术小结

对这个项目中使用的技术,接下来计划做一个完整的梳理和总结,以每周3篇的速度进行。

  • React组件的三种实现方式
  • Fetch 替代Ajax
  • dva 框架
  • dva-loading
  • redux-saga
  • react-redux
  • React stateless component 使用 this.refs
  • HTML5 上传文件
  • React 一维码(react-barcode, JsBarcode )
  • HTML5 打印
  • Chrome调试JS技巧
2017-03-26    
希望的博客

我的博客

生命不止,折腾不息;

还是按捺不住爱折腾的心,搭建自己的博客。总感觉在博客园或者CSDN里写博客,少些什么似乎的,总觉得缺点什么。

寻寻觅觅,有许多可选的方案(Hexo,WordPress,Jekyll…),因为喜欢Golang的缘故,所以对Hugo有种特殊的感觉,也没有太多深入的比较,就选择Hugo了。

这就当我的第一篇博客了,不知道未来会有什么奇迹变化,但这是一个很好的开端。以后的博客都从这里开始了!要比 博客园-墨梅 更加勤奋才是!

2017-03-09    
Supervisor

supervisor安装配置

Supervisor( http://supervisord.org )是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统。它可以很方便的监听、启动、停止、重启一个或多个进程。用Supervisor管理的进程,当一个进程意外被杀死,supervisort监听到进程死后,会自动将它重新拉起,很方便的做到进程自动恢复的功能,不再需要自己写shell脚本来控制。

2017-02-07    
About Me

编程

  • go
  • svelte/react
  • Bash
  • Docker/Helm
  • c#
  • java

工具流

写作/Markdown

2017-01-01