2020年2月7日星期五

如何开启go test的Benchmark测试的内存分配统计

如何开启go test的Benchmark测试的内存分配统计, 我发现一些教程中的加上-benchmem参数已经没有用了,需要调用b.ReportAllocs()才可以开启。
func BenchmarkIsPalindrome(b *testing.B) {
 b.ReportAllocs()
 for i := 0; i < b.N; i++ {
  IsPalindrome("A man, a plan, a canal: Panama")
 }
}
效果:
pkg: gopl.io/ch11/word2
BenchmarkIsPalindrome-8     2151261        534 ns/op      248 B/op        5 allocs/op
PASS

2020年2月4日星期二

减小golang二进制包的体积的编译命令

go build -trimpath -ldflags "-s -w" test.go
参考链接:https://niconiconi.fun/2019/01/14/reduce-go-binary-file-size/

2020年2月3日星期一

Wallabag教程:从入门到入土

Wallabag是什么?参考如下文章
我们本来最希望的是用这个软件解决下列等等问题:


然而我花费几天搭建和研究了这个软件,却发现这个软件就是一个坑!
存在如下几个最大的问题:
  1. 无法保存原始网页,也因此兼容性极差。这个软件开发者比较偏执,非要把原页面提取图文变成“阅读模式”然后保存。但是它又不能100%确保提取图文成功,更无语的是提取图文失败后什么都没有保存下来,让人恼火和无语。相比之下pocket就有网页视图,可以查看网页。这个问题是最大的最致命的!别的都可以忍。
  2. 使用PHP编写,且设计不合理,性能低下。最明显就比如新增文章的时候,是同步的方法,发送链接给它后,请求会卡在那里直到整个页面都被下载保存完毕,这带来了每次新增页面时几秒的卡顿,用户体验极差。这个操作其实应该是异步的,用户提交链接,加入待爬列表,然后多线程爬取内容,对用户则可以显示这个页面在“排队中”/“爬取中”这样的状态。打开一个页面,渲染都要好久,查看文章等每个操作都卡卡的(我可是8核CPU、4G内存服务器)。
  3. 无法配置代理,为了通过代理爬取网页需要手动vi修改php代码加一行代理设置。
  4. 运行不稳定,需要时不时(1-3天)进行手动一次重启docker。这还是我用的docker,如果不是docker怕是更麻烦。
  5. issue还开了396个呢😓
    保存网页失败
  6. 连续的失败
为此,我浪费了两三天的时间。安息吧,Wallabag!
记录下来,希望看到的朋友不要对wallabag浪费时间了,有这个功夫还不如自己写一个,可能都写完了。

2020年1月31日星期五

如何在Blogger里面插入高亮代码

1. 在“主题背景” --> “修改HTML” --> </head>之前加上如下代码;
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
2. 在“主题背景” --> “自定义” --> “高级” --> “添加CSS” --> 添加如下代码;
.post .code { 
  display: block; /* fixes a strange ie margin bug */
  font-family: Courier New; 
  font-size: 10pt; 
  overflow:auto; 
  background: #f0f0f0 url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAASwCAYAAAAt7rCDAAAABHNCSVQICAgIfAhkiAAAAQJJREFUeJzt0kEKhDAMBdA4zFmbM+W0upqFOhXrDILwsimFR5pfMrXW5jhZr7PwRlxVX8//jNHrGhExjXzdu9c5IiIz+7iqVmB7Hwp4OMa2nhhwN/PRGEMBh3Zjt6KfpzPztxW9MSAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzAMwzB8HS+J9kUTvzEDMwAAAABJRU5ErkJggg==) left top repeat-y;
  border: 1px solid #ccc;
  padding: 10px 10px 10px 21px;
  max-height:200px;
  line-height: 1.2em;
}
3. 最后在HTML编辑模式下添加自己的代码,使用下面的格式:
<pre class="code prettyprint">
some code
</pre>

A Tour of GO - Exercise: Fibonacci closure

Exercise: Fibonacci closure

Let's have some fun with functions.
Implement a fibonacci function that returns a function (a closure) that returns successive fibonacci numbers (0, 1, 1, 2, 3, 5, ...).
package main
import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
 a := 0
 b := 1
 return func() int {
  a, b = b, a+b
  return b - a
 }
}

func main() {
 f := fibonacci()
 for i := 0; i < 10; i++ {
  fmt.Println(f())
 }
}

2020年1月30日星期四

A Tour of Go - Exercise: Maps

Exercise: Maps

Implement WordCount. It should return a map of the counts of each “word” in the string s. The wc.Test function runs a test suite against the provided function and prints success or failure.
You might find strings.Fields helpful.
package main
import (
   "golang.org/x/tour/wc"   "strings")

func WordCount(s string) map[string]int {
   res := make(map[string]int)
   arr := strings.Split(s, " ")
   for _, v := range arr {
      if _, ok := res[v]; !ok {
         res[v] = 1      } else {
         res[v] ++
      }
   }
   return res}

func main() {
   wc.Test(WordCount)
}
运行输出:
PASS
 f("I am learning Go!") = 
 map[string]int{"Go!":1, "I":1, "am":1, "learning":1}
PASS
 f("The quick brown fox jumped over the lazy dog.") = 
 map[string]int{"The":1, "brown":1, "dog.":1, "fox":1, "jumped":1, "lazy":1, "over":1, "quick":1, "the":1}
PASS
 f("I ate a donut. Then I ate another donut.") = 
 map[string]int{"I":2, "Then":1, "a":1, "another":1, "ate":2, "donut.":2}
PASS
 f("A man a plan a canal panama.") = 
 map[string]int{"A":1, "a":2, "canal":1, "man":1, "panama.":1, "plan":1}

变量逃逸:golang函数中分配的变量,函数结束的时候不会被释放吗?

我们注意到有如下函数:
func newInt *int {
    var i int
    return &i   //为何可以返回局部变量呢?
}
someInt := newInt()
在Go中变量或者对象的保存不一定必须在栈或者堆中的,Go语言会根据变量在函数中的生命周期有关系,如果变量仅在函数中引用,那么就会保存在栈中,函数结束变量从栈中移除。如果函数中的变量不只是在函数中使用,比如列子中的,那么会将变量保存在堆中,所以列子中的变量是可以返回的,这就是Go的变量逃逸。
参考链接:
Go语言变量逃逸分析 - C语言中文网