Algorithm
func longestPalindromeSubseq(s string) int {
n := len(s)
dp := make([][]int, n)
for i := range dp {
dp[i] = make([]int, n)
}
for i := n - 1; i >= 0; i-- {
dp[i][i] = 1
for j := i + 1; j < n; j++ {
if s[i] == s[j] {
dp[i][j] = dp[i+1][j-1] + 2
} else {
dp[i][j] = max(dp[i+1][j], dp[i][j-1])
}
}
}
return dp[0][n-1]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
Review
Go: when pointers hide the benefits of CPU caching
- 当你的struct的大小小于32kb的时候,建议不使用指针方式进行传值。这样子可以充分利用CPU L1缓存,同时也能够减少使用指针造成的内存逃逸导致GC耗时高的问题。
- 当你的struct大小大于32kb,小于262,144kb,这时候传值使用的是CPU L2缓存,这时候传值的时候进行的拷贝性能损耗已经和CPU L2缓存的优化差不多。
- 当你的struct大于262,144kb,这时候走的是CPU L3缓存,传值的时候进行的拷贝性能损耗远远超过缓存优化,建议传指针。不过传指针容易造成内存逃逸,导致GC耗时高,具体情况具体分析并进行优化。
TIP
这周了解了下市面上常用&公司内部redis的分布式架构:
- 单机架构,存在单个master redis server和多个slave redis server。master节点承担读写请求,slave承担读请求。性能、容量不可扩展。
- 哨兵模式,在单机架构上进行扩展,同样是一主多从的集群环境,只是如果主服务器宕机了,它会自动的将从服务器中的一台设为新的master,并且将其余的slave的配置文件自动修改,这样就切换出一套新的主从服务。性能、容量扩展较差
- 集群模式,存在多主多从的集群架构,主和主、主和从之间异步数据同步。同样的,master承担读写操作,slave只承担读操作。读写请求会按照key进行hash,slot 到不同的master/slave分片上,从而提高整体读写上限。广播机制,当集群>300 ,容易造成广播风暴,性能迅速下降。性能、容量扩展性好。
- 公司的架构,在开源的集群模式上进行适配,将集群模式的非中心化广播模式变成中心化管理,从而减少广播风暴,提高了集群整体分片数量上限。
Share
对新同学的培养和父母对小孩子类似,到了一定程度(年纪)就需要放养。
如果因为害怕新同学能力不行耽误工期而每次都把设计方案做的非常详细,只让他按照你的步骤一步一步拧螺丝钉,这样子能力永远无法得到成长。经历过错误和挫折,能力才能快速成长。