如何高效的产生一个随机字符串?这看似是一个简单的问题,但是icza却通过例子,逐步优化,实现了一个更高效的随机字符串的算法。这是来自的来自stackoverflow上的一个问题:How to generate a random string of a fixed length in Go?, 大家群策群力,提出了很好的方案和反馈,尤其是icza的回答。 本文翻译和整理自这条问答。
C和Go相互调用
C可以调用Go,并且Go可以调用C, 如果更进一步呢, C-->Go-->C
或者 Go-->C-->Go
的调用如何实现?
本文通过两个简单的例子帮助你了解这两种复杂的调用关系。本文不涉及两者之间的复杂的数据转换,官方文章C? Go? Cgo!、wiki/cgo和cmd/cgo有一些介绍。
[翻译]15个最常用的GCC编译器参数
原文: 15 Most Frequently Used GCC Compiler Command Line Options 以及评论中大家提供的一些参数。
GCC编译器是一个日常流行的 C 编译器, 很多Linux的发布版本中都带有这个编译器。这篇文章列举了一些最常用的编译参数。
本文中使用下面的C语言实现的例子:
|
|
跳出Go module的泥潭
说明: go module增在快速的成长中,最近每个版本中(1.11 ~ 1.13)都有很大的变动。 建议你阅读官方的wiki了解go module最新的知识: go/wiki/Modules
最新扩展阅读(go 1.13):Go module 再回顾。
Go 1.11 前天已经正式发布了,这个版本包含了两个最重要的feature就是 module
和web assembly
。虽然也有一些简单的教程介绍了go module
的特性,但是基本上都是hello world
的例子,在实践的过程中, 很多人都在“拼命的挣扎”,包括我自己, 从一些qq群、github的issue, twitter上都可以看到大家茫然或者抱怨的语句。
虽然有三个帮助文件go help mod
、go help modules
、go help module-get
可以了解一些go module的用法,但是感觉Go开发组对module
这一特性还是没有很好的做一个全面的介绍,很多情况还得靠大家看源代码或者去猜,比如module下载的文件夹、版本格式的完整声明,module
的最佳实践等,并且当前Go 1.11的实现中还有一些bug,给大家在使用的过程中带来了很大的困难。
我也在摸索中前行, 记录了摸索过程中的一些总结,希望能给还在挣扎中的Gopher一些帮助。
Introduction to Go Modules 是一篇很好的go module 入门介绍, 如果你仔细阅读了它,应该就不需要看本文了。
局部敏感哈希介绍
传统的Hash当源数据有些许的变化的时候生成的哈希值差异也非常的大, 比如:
|
|
s1的哈希值是65396ee4aad0b4f17aacd1c6112ee364
、s2的哈希值是27444ee2d245c3e8e11ed8b9b035c43b
,源数据仅仅是一个逗号的区别,但是哈希值完全不一样。这是我们使用Hash的常见的场景,输出的哈希值经常被称为消息摘要(message digest)或摘要(digest)。
局部敏感哈希(Locality-sensitive hashing, 简称LSH)则不同, LSH则希望相似的源数据计算出来的哈希值越相近越好。
LSH经常用在判重、文章摘要、聚类、相似搜索、近邻查找等场景, 用来减少高维度的数据的维度,相近的数据放在同一个桶中。 比如大规模异常滥用检测:基于局部敏感哈希算法——来自Uber Engineering的实践
完全静态编译一个Go程序
在Docker化的今天, 我们经常需要静态编译一个Go程序,以便方便放在Docker容器中。 即使你没有引用其它的第三方包,只是在程序中使用了标准库net
,你也会发现你编译后的程序依赖glibc,这时候你需要glibc-static库,并且静态连接。
不同的Go版本下静态编译方式还有点不同,在go 1.10下, 下面的方式会尽可能做到静态编译:
|
|
有一个提案请求给编译加一个static
,如果接收了的话也许在将来的go中直接使用static
。
参考文档
ldd、objdump、nm、strings、strip等工具
最近在做Docker镜像的时候发现镜像文件非常大,需要找出程序的依赖库,减少程序的大小,所以整理了一下相关的工具。基本上这些工具都在GNU Binutils中。
GNU Binary Utilities或binutils是一整套的编程语言工具程序,用来处理许多格式的目标文件。当前的版本原本由在Cygnus Solutions的程序员以Binary File Descriptor library(libbfd)所撰写。这个工具程序通常搭配GCC、make、和GDB这些程序来使用。
它包含20个左右的工具,本文介绍了我在创建Docker镜像的时候的使用的几种工具。
ldd
ldd不是GNU Binutils工具集中的一个工具,但是却是一个非常有用的工具, 它可以显示程序或者共享库所需的共享库。
例如:
|
|
依照ldd得手册, 有时候ldd会通过执行程序来获取依赖信息,对于来源不明的程序,执行这些程序可能会带来风险,所以对于来源不明的程序,可以使用objdump
来分析。
objdump
onjdump可以显示目标文件的信息,可以通过参数控制要显示的内容。
比如-p
可以显示文件头内容, 通过grep
可以查看依赖的库。
|
|
甚至可以查看-T
可以查看动态符号表的内容:
|
|
nm
nm显示目标文件的符号。
|
|
strings
strings显示文件中的可打印字符。
|
|
strip
通过上面的工具,可以分析出文件的依赖库,创建Docker镜像的时候只需把所需的依赖库加进去即可。
如果程序本身比较大,可以将程序压缩,去掉不需要的一些数据, 比如使用strip
进行裁剪。
你可以通过参数控制要丢掉的哪些符号。
比如去除符号表和行号信息:
|
|
libtool
Linux下的GNU Libtool是一种属于GNU建构系统的GNU程序设计工具,用来产生便携式的库。这里引用libtool手册的说明:
|
|
MacOS下的libtool时另外一个工具,可以用来创建库:
|
|
ar
可以对静态库做创建、修改和提取的操作。
|
|
otool
比nm更强大,mac还有一个对应的图形化工具——MachOView。
查看依赖动态库:
|
|
查看反汇编代码段:
|
|
解决 error creating overlay mount to /var/lib/docker/overlay2
最近在centos7.1
使用docker运行redis
镜像,出现下面的错误:
|
|
在网上搜索一番后,一个可行的方案如下(改变storage driver类型, 禁用selinux):
- 停止docker服务
|
|
- 清理镜像
|
|
- 修改存储类型
|
|
把空的DOCKER_STORAGE_OPTIONS参数改为overlay:
|
|
- 禁用selinux
|
|
去掉option的--selinux-enabled
- 启动docker应该就可以了
|
|
方案抄自 Ysssssssssssssss的博客 和 redis的讨论: error creating overlay mount to .../merged: invalid argument., 基本可以确定是启用selinux导致的。