DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

原文链接

They leak if end up either blocked forever on I/O like channel communication or fall into infinite loops. Even blocked goroutine consumes resources so the program may use more memory than actually needed or eventually run out of memory and crash

Sending to a channel without receiver

channel部分的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import "github.com/google/gops/agent"
...
if err := agent.Start(); err != nil {
log.Fatal(err)
}
time.Sleep(time.Hour)
> ./bin/gops
12365 gops (/Users/mlowicki/projects/golang/spec/bin/gops)
12336* lab (/Users/mlowicki/projects/golang/spec/bin/lab)
> ./bin/gops vitals -p=12336
goroutines: 14
OS threads: 9
GOMAXPROCS: 4
num CPU: 4

通过gops的引入

runtime.Stack的方式

Stack formats a stack trace of the calling goroutine into buf and returns the number of bytes written to buf. If all is true, Stack formats stack traces of all other goroutines into buf after the trace for the current goroutine.

原文链接

our TSDB backup system has several components that need to be monitored, including a metadata database, external storage, backup agents, and a centralized backup scheduler, along with with performance metrics such as network throughput, CPU utilization, memory utilization, and disk performance.

expose application metric

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import (
"encoding/json"
"log"
"net/http"
"runtime"
)

func Performance(w http.ResponseWriter, req *http.Request) {
results := make(map[string]float32)

// get number of Goroutines
// https://golang.org/pkg/runtime/#NumGoroutine
numRoutines := runtime.NumGoroutine()
results["GoRoutines"] = float32(numRoutines)

// get memory stats
// https://golang.org/pkg/runtime/#MemStats
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)

// bytes allocated and not yet freed
results["MemAlloc"] = float32(memStats.Alloc)

// number of frees
results["MemFrees"] = float32(memStats.Frees)

// bytes allocated and not yet freed
results["MemHeapAlloc"] = float32(memStats.HeapAlloc)

// bytes in idle spans
results["MemHeapIdle"] = float32(memStats.HeapIdle)

// bytes in non-idle span
results["MemHeapInUse"] = float32(memStats.HeapInuse)

// total number of allocated objects
results["MemHeapObjects"] = float32(memStats.HeapObjects)

// bytes obtained from system
results["MemHeapSys"] = float32(memStats.HeapSys)

// number of mallocs
results["MemMallocs"] = float32(memStats.Mallocs)

// total number of garbage collections
results["MemNumGc"] = float32(memStats.NumGC)

//total time that the garbage collector has paused the program
results["MemPauseTotalNs"] = float32(memStats.PauseTotalNs)

// bytes obtained from system
results["MemSys"] = float32(memStats.Sys)

resp, err := json.Marshal(results)
if err != nil {
log.Printf("error: couldn't marshal queue metrics to json")
w.WriteHeader(http.StatusInternalServerError)
} else {
w.Write(resp)
}
}

将这些收集到的内容,放到TSDB里中,(json格式)

mysql的索引部分:关于最左匹配部分

在使用查询的时候遵循mysql组合索引的”最左前缀”,下面我们来分析一下 什么是最左前缀:及索引where时的条件要按照建立索引的时候字段的排序方式

1、不按索引最左列开始查询(多列索引) 例如index(‘c1’, ‘c2’, ‘c3’) where ‘c2’ = ‘aaa’ 不使用索引,where c2 = aaa and c3=sss 不能使用索引

2、查询中某个列有范围查询,则其右边的所有列都无法使用查询(多列查询)

Where c1= ‘xxx’ and c2 like = ‘aa%’ and c3=’sss’ 改查询只会使用索引中的前两列,因为like是范围查询

3、不能跳过某个字段来进行查询,这样利用不到索引,比如我的sql 是

explain select * from award where nickname > ‘rSUQFzpkDz3R’ and account = ‘DYxJoqZq2rd7’ and created_time = 1449567822; 那么这时候他使用不到其组合索引.

因为我的索引是 (nickname, account, created_time),如果第一个字段出现 范围符号的查找,那么将不会用到索引,如果我是第二个或者第三个字段使用范围符号的查找,那么他会利用索引,利用的索引是(nickname),

mysql在使用like查询的时候只有不以%开头的时候,才会使用到索引。

给一个随时会断掉的输入流,取100个输入,保证尽可能的公平

先取100个,再按照一定的比率,取后面的数据,同时按照一定的概率对之前选取的数据进行替换,采用类似ping-pong的机制,通过一定概率进行替换

关于twitter的Finagle框架 rpc框架 同gRPC的区别?

都是rpc部分的框架,

关于goroutine的使用方面,关于使用了多少个goroutine,内存占用的情况

可能来说,监测内存占用情况,比较合适,runtime上去计算多少个goroutine上,有点不是很实用

go与java的区别

关于多线程的实现方式,一个是1:1对应到操作系统的线程,一个是n:m:p的方式,

finally以及defer之间

function部分多个返回值部分

部署的方便性部分,二进制文件以及jar包

在起多线程方式上,java还有哪些方式?thread/runnable/callable、future部分

nodejs的一些优缺点

事件驱动,非阻塞IO,单进程,单线程,callback机制,

emet的方式?

遇到I/O操作,会再起一个线程,不跟主线程冲突,适合I/O密集型应用

tcp的三次握手以及四次挥手

tcp

tcp为全双工的,

简单说来是 “先关读,后关写”,一共需要四个阶段。以客户机发起关闭连接为例:

1.服务器读通道关闭

2.客户机写通道关闭

3.客户机读通道关闭

4.服务器写通道关闭

IO模型

阻塞、非阻塞,针对应用来说,非阻塞也是轮询的那种

IO多路复用,主要是内核给出相关的信息,如select、poll、epoll

异步通讯,就是服务端来控制传输,无需客户端询问的那种

同步过程中进程触发IO操作并等待或者轮询的去查看IO操作是否完成。异步过程中进程触发IO操作以后,直接返回,做自己的事情,IO交给内核来处理,完成后内核通知进程IO完成

需要做一件事能不能立即得到返回应答,如果不能立即获得返回,需要等待,那就阻塞了,否则就可以理解为非阻塞

设计一个内存分配算法

slab算法

slab算法

分布式系统的设计几个点

稳定性,不允许单点失效

尽可能减少节点间通讯开销

应用服务最好做成无状态的

CAP理论:一致性,可用性,分区容忍性(可靠性), 带来的一个问题,是ACID理论,(原子性,一致性,隔离性,持久性)

选主算法方面的问题,关于paxos算法的解释,以及raft协议的阐述

docker

1
2
3
4
5
适用于弹性部署的场景,例如抢购,秒杀,服务压力骤增,需要短时间增加容器。

同时适用于分布式情况,毕竟分布式部署应用还需要考虑,单点故障的情况。

还有就是异步处理任务,配合动态增减服务器,就可以节省资源,降低成本

编排的目的:服务发现,高可用,资源管理,端口管理

各种编排的策略:swarm, k8s,双方提供的功能不同,

linux中buffers和cached

used:表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用。

free:未被分配的内存。

shared:共享内存,一般系统不会用到,这里也不讨论。

buffers:系统分配但未被使用的buffers 数量。

cached:系统分配但未被使用的cache 数量

buffers是指用来给块设备做的缓冲大小,他只记录文件系统的metadata以及 tracking in-flight pages.

cached是用来给文件做缓冲。

那就是说:buffers是用来存储,目录里面有什么内容,权限等等。

而cached直接用来记忆我们打开的文件

三年来的第一次面试,算是勉勉强强地过了

期间一些问题的回顾

  • 简历上关于新美的部分,有些太少,应该多加点,并且侧重于数据以及优化
  • 创业公司,一个人干成一个大工程,要强调这部分的一个挑战性,包括技术上的挑战性,沟通上的挑战性,最后成果上的展现的挑战性
  • 关于成长性的预期,是从大公司的一个螺丝钉到创业公司的独当一面,强调现有工作的全面性
  • 从内部系统转向了外部系统,从并发性以及复杂性上,给出相应的答案
    • 输入法后端的并发性
    • 推送系统的完备性
    • 数据平台的完整性,多维度性
    • 处理框架的实时性上
    • 多机房部署的复杂性,以及运维上的复杂性
  • 尽量从数据上给出例子
    • qps,接口成功率
    • 推送系统的成功率,推送的及时性
    • 离线处理平台部分,涉及多日志处理部分,完整性,复杂性
    • 在线处理平台的实时性,框架的选择,结果的呈现
    • 其他一些技术上的选择,以及成果

twitter的fingle框架-> 为什么不用gRPC框架,后续来说。。

技术上的专家部分->广度的专家->深度上的专家


继续第二面部分

方向上的一些兴趣点部分?

对于基础上的预习不够

简历上关于语言的写法有问题,导致很多还以为会php。。。还是关于侧重点方面,有点牵强

了解地多,还要了解地深,很容易给别人的感觉就是杂而不精。。

不过,经过这次的面试,愈发觉得谦卑的重要性,不管是大公司还是小公司,不管身处什么职位,任何人都有其平等对待的必要,而不是一种店大欺客的感觉。。。

面试也是一种学习和了解,摆好心态,争取自己在面试中学习到更多。。

同时,算法还是偏弱,还要继续刷leetcode。。。


所谓的人情三面,终于体会到了。。。

关于业务和技术方面,最终的方向是什么?还是给什么做什么?

传说中的技术上的专家部分,是否还有机会?

关于kafka的一个整合部分,关于规范producer以及consumer部分,以及对突发流量部分的一个把控部分,还是挺有启发的。。

在面试的时候,不用考虑去迎合面试官,尝试去表达自己的想法,尽量坚定自己的想法,不用随着面试官去摇摆,虽然有各种压力和想法,但面试当做学习的话,也要表现自己的思路,自己优点在哪里。。尽量不要紧张。。

在面试中去寻找自己感兴趣的部分,觉得有用的地方。。


第四范式的面试:

  • 关于内存池分配问题,多线程部分,每个线程独立一个内存池,缓存的局部性
  • 算法题,还算是蒙对了。。

技术经理面的时候,会问一些关于管理风格上的问题,以及自己在遇到一些不如人意的环境下,会如何处理的问题。不过,感觉还是有点没答好,关于未来的方向上,有什么遗憾之类。。

最后面的时候,对岗位的match程度产生了怀疑,不过自己也在介绍的时候,没有说好,只是在说明自己对于底层这块有兴趣,但是实际上的一些经验上,没有表述清楚,没有表达自己对于底层优势的部分?

关于业界的最佳实践部分,并不算最佳实践部分,在对于业务的方向上,去选取对业务更合适的架构,并从这其中发现更多的问题,解决这些问题,包括应用层,以及底层部分,都可以去优化。。


freewheel的面试:

  • 关于数据的严谨性部分,如丢失率部分,有没有计算?
  • api gateway的方式,关于限流部分,有没有更好的方式,除了丢弃之外,通过redis来实现限流器部分,
  • 关于服务的测试/上线部分,通过gor replay部分,对相关流量进行还原

关于数据的lazy data问题,可能还是基于时间窗口部分,本地状态的一个概念?本地缓存的一个概念

规定一个时间段用于重排乱序的事件,同时也具有在一定时间段内重排乱序事件的能力

nosql的一些策略

  • hbase
  • mongodb

版本和索引的概念

基于raft协议的golang的实现部分?分布式锁的情况,其实没有说到选举部分,这一点有点没答出来,只是有一个分布式锁的状况

关于数据的反馈是如何来做?类似于广告的策略的改变部分?

后面两面部分:

关于数据的质量保证部分,是如何来保证,这个按照面试官的说法,没有答好,这块无非就是事前的测试部分完备性,以及事后的及时恢复性部分,事前测试的完备性,在于一个测试环境以及相关功能的测试的引入,包含流量的复制,相关代码的单测部分,功能测试,压测等等。事后的及时恢复,在于事件的及时通知问题,通知完成之后,自动恢复的部分,对相关数据以及应用的影响部分的预估。

说到自己的缺点的时候,有点太随意了,细节把控部分不仔细,举的例子上,对于上线后的检查部分,有点跟之前质量保证部分,有所冲突。。。有点没答好

关于lazy data的问题,其实做的思路都差不多,将时间戳部分能够继承到后续的数据中,方便进行数据的修正;具有一段时间时间数据的保存功能,方便进行数据的重处理功能

对于系统的复杂性部分,运维上,稳定性上,分布式上,还有灵活性,正确性等等。。


今日头条的面试:

  • 关于基础知识的不确定,如rune<->int8部分,数据库的索引部分
  • 算法的顺序反了。。

关于百度业务的总结,以及分拆部分,

原文链接

IPFS stands for InterPlanetary File System, but you could simply consider it as a distributed, permanent, but ridiculously slow, not properly functioning version of web.

ref: https://ipfs.io/

Every IPFS node’s default storage is 10GB, and a single node could only store data it needs, which also means each node only stores a small amount of whole data on IPFS. If there is not enough nodes, your data might be distributed to no one except your own node.

ipfs add类似git方式?hash code的方式

Pinning means storing IPFS files on local node, and prevent them from getting garbage collected. Also, you could access them much quickly. You only need to do ipfs pin add to pin contents someone else uploaded.

Get files? 通过hash值去get相关的文件?

IPNS stands for InterPlanetary Naming System.

Everytime you change files under a folder, the hash of the folder also changes. So you need a static reference which always points to the latest hash of your folder. You could publish your static website (a folder) to IPNS with the static reference, which is your peer ID as well as the hash of your public key.

publish a website to ipns

After you change something, publish it again with new hash.

Create a Domain Name Alias for Your Peer ID

可以取别名,这是优于git部分的feature?