無標題文檔

迁移到 Google Cloud Platform

Google Cloud Platform

好吧,又是个比较蛋疼的经历。后来由于发现 Azure 的香港线路非常不友好(电信),最后还是迁移到了 Google Cloud Platform,话说我真的不想再迁移了。

有国际信用卡还是方便的,根据我目前的配置 Google Cloud Platform 几乎可以实打实用一年。据说 Google Cloud Platform 的流量费用还是不便宜的,所以到时候做些必要的优化(虽然访问量其实不高)。后面的具体费用,等账单出来以后再观察。

Microsoft Azure

如果您能看到这篇博客,那么说明站点迁移到 Microsoft Azure 已经完成了。

其实并不是原先的 Linode 空间不好,而是某些不可抗力导致 Linode 日本节点在中国大陆的可用 IP 越来越少。顺便说一句,Vultr 更甚几乎可以说是全军覆没。

虽然相比 Linode,Azure 的性价比并不是很高,但是它有个「东亚」节点(其实就是香港)对于国内线路优化很好。如果不考虑性价比这块的话,Azure 其实也算是个很好的去处。

那么为什么不迁移到阿里云的香港节点呢?嗯,咱聊点别的吧…

整理汇总下最近用 Golang 写的些小玩意

由于工作的关系,所以又点了 Golang 这个技能树。几个月下来,对于这个语言以及对应技术栈的理解不算透彻,但多多少少会有些心得。

在这里整理下最近用 Golang 写的些小工具以及类库,希望能对大家有所帮助。

Genpasswd 简单的密码生成工具

源码地址:https://github.com/mingcheng/genpasswd.go ,根据名字就知道这是个生成随机密码的小工具。这个项目是本人的第一个 Goalng 项目,主要是熟练使用了些对应的脚本和配套的 CI 等工具(Travis 非常好用)。

QQWry 基于纯真 IP 库的微服务应用

源码地址:https://github.com/mingcheng/qqwry.go ,根据 IP 地址反查对应的地理位置等信息。

纯真 IP 库其实不是新东西了,早在以前 QQ 时代显示对方的 IP 信息就基本上会拿这个库来处理。其实,这个项目也只是根据线上现成的项目改进了下,使其支持在线获取以及更新最新的数据库(后续考虑增加 GRPC 的支持)。

NCMDump 云音乐 NCM 格式分析

源码地址: https://github.com/mingcheng/ncmdump.go ,云音乐出于版权方面的考虑有些歌曲在下载到本地的时候,格式是所谓的 NCM 格式。这在导入到其他设备的时候会有些麻烦。

网络上有对应的 C++ 以及 Python 的实现。其实也有对应 Golang 的实现,但会有些 Bug 例如解析某些 flac 封装的歌曲的时候会报异常,所以改进了下。通过这个项目,对于 AES 加密以及文件操作有了很直观的认知。

PIDFile 生成 PID 文件的库

源码地址:https://github.com/mingcheng/pidfile ,由于些 Golang 通常用于 Daemon 的编写,所以会考虑使用 PID 文件避免程序重复启动,因此就有了这个库。

Obsync 华为对象存储同步工具

源码地址:https://github.com/mingcheng/obsync.go ,尝试使用了下华为云的对象存储服务(OBS),发现支持的节点不错而且对比阿里云相对便宜些。诡异的是它还有非洲的节点,速度也不慢电信直连。

这样子,我的线上备份以及同步就有了另外个去处,数据方面也会安心一点。在中美这个节点上,支持下华为吧。

最后,顺便说下 Chaosblade 这个项目,它是阿里的混沌实验实施工具。其源代码相对来说不会很复杂,可以阅读下以后多给它做些改进。

One more thing. 还有个小玩意是 NSFW 的,我改造了下使其支持代理下载,具体的看链接吧:https://github.com/mingcheng/pornhub-dl.go

- eof -

使用多个版本交叉编译 Golang 项目

在编写内部项目中,往往不同的项目因为历史遗留问题,会有存在多个版本的 golang 编译器共存的情况。

同时,由于 golang 的包管理的短板(虽然在 golang 1.11 以后推出了 go mod),因此不可避免的安装 govendorgo dep 等多个包管理工具,非常的混乱。

本地使用多个 golang 的编译器版本其实更容易造成混乱,同时 env 满天飞也非常不方面维护。解决这块的问题很容易就想到了使用 Docker 去编译和检查本地项目, Docker 官方维护了多个版本的 golang 镜像

那么考虑的目标是:

  1. 使用同一个 Makefile 以及 Dockerfile 去维护项目的编译
  2. 因为 golang 1.11 以后官方推出了 go mod,所以尽量使用官方的包管理工具
  3. 接上条,老版本的依赖和本地编译使用 go mod vendor 去管理
  4. Makefile 不管 golang 编译器的版本问题,编译器版本让 Dockerfile 去管理
  5. 本地环境尽量使用最新版本的 golang 编译器,然后导入到 vendor 中

那么这样子,我们可以简单的使用 Dockerfile 去编译执行,例如下面使用编译器版本 golang 1.9.7 类似:

FROM golang:1.9.7 AS builder
# ...
RUN go build .
# ...

但需要注意的是,golang 1.11 之前必须代码在 $GOPATH 中,所以需要映射

ENV GOPATH /go
ENV GOROOT /usr/local/go
ENV PACKAGE ${YOUR_PACKAGE_NAME}
ENV BUILD_DIR ${GOPATH}/src/${PACKAGE}

# ...
COPY . ${BUILD_DIR}

然后在本地使用 go mod vendor 下载依赖包到项目的 /vendor 就可以在老版本中免去使用 dep、govendor 等依赖工具,统一使用官方的 go mod 去管理和下载依赖。

还有需要关注的是 Makefile 需要加个判断,为了增加通用性,建议根据路径判断 golang 的环境路径,而不是判断是否在 Docker 环境下:

# ...
ifneq ("$(wildcard /go)","")
    GOPATH=/go
    GOROOT=/usr/local/go
endif

GO=env $(GO_ENV) $(GOROOT)/bin/go

# ...

build:$(DIR_SRC)/main.go
    @$(GO) build $(GO_FLAGS) -o $(BIN) $(DIR_SRC)

这样子 Makefile 文件就可以同时同于本地高版本的环境以及 Docker 编译环境了。

详细的示例代码可以参看 这个简单的项目(作用只是用于生成随机密码),其中的 Makefile 以及 Dockerfile

最后,有个讨论 vendor 目录到底要不要纳入到版本控制中?我个人的看法是看情况,大部分情况下不会将这些第三方代码纳入版本控制中。主要的理由有:

  1. 这些代码是第三方库的代码,不会直接更改以及维护;
  2. go.mod 以及 go.sum 文件已经保存了第三方依赖的库信息(版本、hash 等等);
  3. 库文件通常会很多,纳入这些的文件会「污染」本地的 git history;
  4. 不同于开源项目,我们本地的开发环境是可控的。

所以,类似的 Consul 等比较大型的项目还是会将 vendor 目录纳入到版本控制中,个人认为这也是因为兼容方面的考虑更多些,而如果个本地项目往往环境是可控的。

- eof -

记次网桥的 Mac 地址改变导致无法链接的问题

家里的小服务器装的是 ArchLinux,在有次 pacman -Syu 以后发现无法连接了,登录上去以后发现原来是网桥的 Mac 地址没有复制过来,导致路由器无法根据 Mac 地址分配正确的 IP 地址。

# ip link show br0
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether <mac> brd ff:ff:ff:ff:ff:ff
# ip link show eno1
2: eno1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP mode DEFAULT group default qlen 1000 link/ether <mac2> ff:ff:ff:ff:ff:ff

原先的网桥配置如下

$ cat /etc/netctl/bridge
Description="Bridge Connection for KVM"
Interface=br0
IP=no
Connection=bridge
BindsToInterfaces=(eno1)
MACAddressOf="eno1"
## Ignore (R)STP and immediately activate the bridge
SkipForwardingDelay=yes

根据配置上的定义 MACAddressOf="eno1" 为复制 eno1 的 Mac 地址,这样子网桥和网卡的 Mac 地址应该一致才是。不知道为何更新重启以后就无法复制 Mac 地址了。

查看了相关的文档,用换了一种方式绑定网卡的 Mac 地址:

$ cat /etc/netctl/bridge
Description="Bridge Connection for KVM"
Interface=br0
IP=no
Connection=bridge
BindsToInterfaces=(eno1)
#MACAddressOf="eno1"
ExecUpPost="ip link set dev br0 address $(cat /sys/class/net/eno1/address); IP=dhcp; ip_set"
ExecDownPre="IP=dhcp"
## Ignore (R)STP and immediately activate the bridge
SkipForwardingDelay=yes

其中,主要是以下两行

ExecUpPost="ip link set dev br0 address $(cat /sys/class/net/eno1/address); IP=dhcp; ip_set"
ExecDownPre="IP=dhcp"

由于 dhcp 让 hook 去获取了,所以务必设置为 IP=no,否则会重复释放 IP 导致网桥无法建立。以下是相关的参考连接:

技术人员如何做好职级晋升答辩

三月即将过去四月份即将到来,很多公司年后的职级晋升安排即将结束。

同时,晋升的结果也将陆陆续续公布出来。几家欢喜几家愁,晋升成功的同事自然值得祝贺,没有过的同事也不要气馁再接再励。

对于技术人员而言,普遍有个很共通的现象,就是往往过于深入技术,忽略了平时对于沟通等所谓「软性素质」的培养和意识,造成可能无法表现出自己真正能力。下面,说说我对职级晋升的一些认知以及经验。

准备阶段

内容控制

通常来说,职级晋升是对去年整年的总结以及回顾,因此从时间的角度上考虑,答辩的内容应该尽量控制在这一年的区间范围内。当然,如果有项目的时间跨度比较长的,应该说明原因同时更需要说明自我在此项目中起到的作用。

往往,主管也答辩人都会犯一个错误,就是将「认为很厉害」的内容和技术点作为答辩的内容,这往往是有偏差的。答辩的内容选题应该从目标职级的角度出发,从目标职级考虑选送的答辩内容是否适合这个职位。

同时,需要根据答辩的时间(自述通常不会超过半小时)来确定选题的数量。因此,答辩的选题是非常重要的,往往选题错误就造成答辩方向的错误。

PPT 是门面

从 PPT 设计的角度上说,技术人员在这块的问题很有典型性,就是往往会将大段的代码(或者截图)贴到 PPT 上。

这会让评委对于内容方面会造成一定的困扰:首先,答辩过程中评委不可能对这块代码进行 Review;其次,从摘抄的这段代码来说也不能体现答辩者应有的水平。

所以,正确的做法应该是觉得需要感觉贴代码解释的地方,尽量贴流程图或者架构图或者 UML,如果还是感觉说不清楚那么建议考虑要不要简化和突出这块想要表述的内容。

技术人员的 PPT 还有个问题就是有太多的文字,这往往会造成表意不清晰。所以,个人的经验就是如果这个 PPT 超过了 200 个字,那么就应该考虑精简。

对 PPT 设计方面的技巧在这块不铺开讲述,网络上已经有更翔实的内容可以找到。

思路和角度很重要

同样的事情,去使用不同的角度去表述,往往返回的结果是不一样的。对于技术人员而言,很容易犯的错误就是将事物「描述得平淡无奇」。这让评委在答辩过程中感觉不到你在这个项目中起到的作用,以及你对这块事物的理解。

例如,有做业务的同学描述了很多对于整个系统的业务以及架构方面的设计,甚至业务的流程是如何流转。但是,根据评委的判断这是团队行为和输出,在答辩的描述中没有体现出其个人对于这个业务的思考和沉淀,以及起到的作用的影响。

所以,对于做业务的同学往往会觉得可能在技术的角度来看,光技术会觉得不够深入。但,换个角度考虑如果结合你对业务的理解,并融合到技术中输出技术的解决方案,那么高度就会不一样。

排练、排练、再排练

答辩的过程和时间是很紧凑的,因此在正式开始答辩前,进行自我排练是非常有必要的。如果条件允许,建议答辩人的主管都能把关一轮,往往在排练过程中就会发现各种问题:答辩人讲述 PPT 的时间、语速以及表达方式能力,等等。

答辩过程中

情绪控制

紧张的情绪能够毁掉所有,甚至让你说话都不利索,尤其作为「相对内向」的技术人员,这块是相对普遍存在的。因此,在答辩开始之前就应该控制和放松自己的情绪,不要过于紧张。

如果过于紧张,这里有个 Tips 可以考虑下:就是作为答辩人你可以认为这是一场技术交流,你尝试说明自己所做的工作以及出彩的地方,让对方觉得自己「很厉害」。

从评委侧也应该给予正向引导,例如答辩人进场的时候打个招呼寒暄一下,也会起到比较好的效果。

节奏控制

答辩开始需要自我介绍,建议两三句话讲重点,千万不要拖泥带水同时夹带不必要的信息。一个失败的自我介绍可能就会毁了整个答辩,毕竟这是你给评委的第一印象。

像上面说的,如果觉得很紧张,那么自我介绍的时候可以稍微刻意放慢下语速,可能会起到调节的作用。

从自我介绍转入到正题的转场口白要自然,如果控制不好演讲的技巧(也不知道应该说什么),那么万精油的一句「下面,我开始我的工作内容介绍」。

在表述 PPT 过程中语速尽量使用中速,前面说的如果排练过那根据内容以及语速,就能找到很好的平衡点。

其实还有个技巧,如果某个技术点很深入或者需要探讨,可以将这个点当作个包袱先抖出来,留给评委后面提问的时候解答。

评委的意图

需要意识到的一个点就是,评委问的所有的问题都有其含义的。如果你的回答让他抓不到他想要的点,那么你的得分会不一定很高的。

例如,当评委问你「这个系统设计的时候,你当时考虑了哪些方面」?这个问题其实反映出两个点:其一,就是你刚才答辩描述的时候没有讲透彻,或者说深度还不够;其二,评委需要个抓手需要了解你对这块的个人理解。

所以,当你回答这个问题的时候,无论从什么角度出发,千万千万不要再介绍业务和系统本身的内容了!应该从自己对这个系统的理解和沉淀出发去阐述自己的理解,如果能表达有一定的输出以及对同事和团队的影响就更好。

答辩后

关注结果、Review 自己

评委对于答辩者的评价是主观的,但是相对答辩的过程其实是客观的。这话说起来可能会有点矛盾,但从「师以质疑,友以折疑」的角度出发, 评委的评价是需要去深入理解的。

对于个人而言,晋升答辩是对过去工作的总结和评价,而不是代表对于未来工作的期待和展望。无论是自我表达的原因,也可能是评委理解不同的原因,评委对答辩者的评价都是不同的,这块需要个人辩证得去理解。

换个角度上考虑,如果你当晋升答辩是一场面试,那么这将是很好理解的一场过程了,而且这场面试的还能看到「面试官」对于自己的评价,何乐而不为呢?

资源和环境

当我们上升个高度去考虑职级晋升的时候,往往就不可避免得聊到职业规划和发展这个老生常谈的问题。

无论答辩的结果怎么样,我们更应该考虑以后的发展。首先,考虑的是个人对于自我提升这块,满足了自我的期望和要求没有;然后,再考虑公司能够提供的环境,能否有个上升的正向上升空间?

能够回答这两个问题,那么自然而然,对于职级这块的理解和态度也就是水到渠成的事情了。

-- eof --

我的照片

嗨!我叫「明城」,八零后、码农、宁波佬,现居杭州。除了这里,同时也欢迎您关注我的 GitHubTwitterInstagram 等。

这个 Blog 原先的名字叫 Gracecode.com 、现在叫 「無標題文檔」 。 其实无所谓叫什么名字,作为码农知道取名是件很难的事情。最后想到的这个名字,其实都没啥特别的含义,系统默认的文件名而已。

作为八零后,自认为还仅存点傲娇式的幽默感,以及对平淡生活的追求和向往。 为了免得对号入座和不必要的麻烦,声明本站点所持观点仅代表个人意见,不代表自己所服务公司的立场。

如果您想联系我,可以发我邮件 `echo bWluZ2NoZW5nQGdyYWNlY29kZS5jb20K | base64 -d`

文章

项目