我该学编程吗?

有部分朋友面临这个困惑。

  • 一种是互联网行业的非技术岗,能接触到 IT 技术人员,对编程有一定认识,知道这个对工作有帮助,想学。但怕学不来,不知道怎么学。
  • 另一种是完全没有接触,只是大概听说 IT 行业前(钱)景好。听说哪哪地方编程进课堂。然后碰见广告,或者大街上宣传学编程,产生了疑问:我(我的孩子)该学编程吗?

阅读全文

Flutter 踩坑流水账

Flutter 作为前端一个发展方向大热,有必要了解一下。

踩坑流水账,遇到啥记啥,不求全;遇到的 弯弯绕绕,错误示范如实记载 。当前 Flutter 还不太稳定,可能过一段时间操作细节就变了(希望是改进),这种记录可以跟将来做对比。

阅读全文

配置 1.13+ 的 golang 环境(Windows 篇)

前段时间为 go 1.13 写了 《配置 1.13+ 的 golang 环境》 (注:现在go 1.14 都发布了),以区别于 1.9 还在用 GOPATH 时写的 《配置 Golang 开发环境》 。考虑到后者写了 Win 环境下的配置,于是前者就写一下 Linux 环境。

当下这个时间点,当然参考 1.13+ 那篇。可是在 Windows 配置怎么办?那就把文中系统相关的操作(主要是环境变量)换成 Win 的对应操作。两篇文章,分别涉及到了 “< 1.13 & Win” 和 “1.13+ & Linux”,看完举一反三,应该新旧版本两个系统平台,都会配置了。

结果今晚让朋友看着新教程(1.13+)配置 Win 下 go 1.13+ 环境,证明我还是太天真:这些配置教程的目标读者很可能根本没有跨平台的经验,一个 Linux 的操作在 Windows 下对应着什么,他们完全没有概念 [摊手]。

一气之下,只好再发一篇。注意,这篇 没有任何新内容,纯粹是旧文的重新组合!(Windows & go 1.13+)

阅读全文

删除打开文件的正确方法(Linux)

凭记忆复述一个坑,稍微带到 Linux 文件系统知识。时间久远,记忆可能存在差错。发现了错误请留言告知,感激不尽。

标题的中文断句上容易有歧义,重复一下英文:correct way to delete an opened file ,关键在 『打开了的文件』或者叫 『已经打开的文件』,怎么解释都比 opened 拗口。

(由于当时没有留下记录,文中 shell 输出均为写文章时 模拟重现,并非第一现场。)

阅读全文

配置 1.13+ 的 golang 环境

以前写过《配置 Golang 开发环境》(go < 1.13, win64)。然后 1.13 是一个重大变更,大到需要原有的依赖管理要做迁移的程度(《golang 1.13 - 依赖管理从 dep 到 mod 踩坑》)。

1.13 让原来的配置方式有了变化,撇开语言特性不谈,仅说和配置相关的,最大的变化,是 go module 的转正,和 GOPATH 和 vendor 的边缘化(1.13 仍然给你选择的余地,但是推荐选择 module,停用 GOPATH 和 vendor)。

那么如果你从 1.13 之后才刚刚开始接触 go, 那么前面两篇文章对你来说并不友好。

所以我找到了理由又水一篇。

阅读全文

golang 1.13 - 依赖管理从 dep 到 mod 踩坑

接触 golang 很晚,实际用来开发大概在 1.9 左右,所以我的主要印象是在 1.9 、 1.10 上的,依赖管理经过一些尝试之后,选择了 『官方』(后来实际被抛弃了)的 dep(《golang 依赖管理:glide 从入门到放弃》)。

后来 1.11、1.12 推出了 module (亦即 go mod 命令),考虑到尚不稳定又有切换成本,就继续留守在 vendor 目录上。

2019 年 9月终于 1.13 出来了,做了几个比较大的改动,同时 module 也终于转正,所以我终于下定决心迁移到 1.13,并改用 mod 做依赖管理。

阅读全文

golang 预置 json 包的值覆盖测试

json 作为一种可读性高、跨平台的序列化手段,常用在持久化和网络间传输。一般情况下,只需考虑是否按照作者的意图序列化和反序列化;反序列化的目标一般是一个 空白的对象,供写入得到的值。

但有一些特殊情况,还要考虑反序列化过程中,值的覆盖性:用到的字段非常多,给每个都赋值很麻烦,所以提供一套默认值(注意默认值不一定是 0 值),只要 json 中没有指定,就转而使用默认值。这在 jQuery 中只需要使用 $.extend(default, opts1, opts2...);而如果想递归合并,则只需要把 true 作为第一个参数。

阅读全文

golang-string 和 bytes 之间的 unsafe 转换

最近写一个 golang 的工具包时,涉及到反复在 string 和 []byte 之间来回转换。这给了我一个机会了解转换时底层发生的事情。

结论先行

  • string 和 []byte 互转都涉及底层数据复制;可以通过 unsafe 强制转换绕过复制提高性能。
  • string 类型的底层数组可能放在常量区(字面量初始化)也可能动态分配;无论哪一种,当以 string 类型出现时底层数据都是不可修改的(避免影响其他引用),string 的修改实际上是指向重新生成的底层数组。
  • 当以 []byte 类型出现时,可以修改具体某一个 byte 的值;不过如果是从指向常量区的 string 通过 unsafe 转换而来,尝试修改时会产生不可恢复的 runtime error。
  • 这也是为什么这个包叫 unsafe:绕过类型检查强行转换,绕过了底层数据复制,提高性能同时也失去了检查和复制的保护,需要调用方自行确认不会出错。
  • + 连接会复制内存,strings.Split() 直接在原串做切片…具体不同实现要以源码为准。
  • 即使 string 是动态分配的内容,也不建议修改对应的 []byte,可能会引起引用同一块内容的其他 string 的异常—— 除非你能确保没有别的地方引用它。
  • 实际调用中碰到了 对 A 串做 unsafe 转换,结果完全无关的 B 串出现切片时数组越界;A 串改为普通转换就好了。暂时没能找到原因,保险起见放弃使用 unsafe,改为用 json.RawMessage 多封装一层。本次研究权当学习了。

阅读全文