System & Network & MISC

I have dreams, and regardless of whether or not they’re realistic, I must work toward them.

System

Network

MISC

估算法 @
斯特林公式,Stirling’s approximation / Stirling’s formula @
Comparison of Stirling’s approximation with the factorial

Comparison of Stirling’s approximation with the factorial

Time value of money - Wikipedia, the free encyclopedia

Method of matched asymptotic expansions - Wikipedia, the free encyclopedia

A tiling with squares whose side lengths are successive Fibonacci numbers

A tiling with squares whose side lengths are successive Fibonacci numbers

refs and see also

TCP 连接的建立和终止过程 - 辛未羊的博客 @
[SYN+SYN/ACK+ACK]

+-------+                           +-------+
|       |   --->--SYN------->---+   |       |           客户端发送一个TCP的SYN=1,Seq=X的包到服务器端口
|       |                       |   |       |
| client|   ---<--SYN/ACK---<---+   | server|           服务器发回SYN=1, ACK=X+1, Seq=Y的响应包
|       |   |                       |       |
|       |   +-->------ACK--->----   |       |           客户端发送ACK=Y+1, Seq=Z
+-------+                           +-------+


[FIN+ACK; FIN+ACK]

+-------+                           +-------+
|       |   --->--FIN------->---+   |       |       主动方发送Fin=1, Ack=Z, Seq= X报文
|       |                       |   |       |
| client|   ---<------ACK---<---+   | server|       被动方发送ACK=X+1, Seq=Z报文
|       |                           |       |
|       |   +--<--FIN-------<----   |       |       被动方发送Fin=1, ACK=X, Seq=Y报文
|       |   |                       |       |
|       |   +-->------ACK--->----   |       |       主动方发送ACK=Y, Seq=X报文
+-------+                           +-------+

Richard Stevens 先生在 UNP2e (UNIX 网络编程 卷 1:套接字联网 API) 的前言中写道:

I have found when teaching network programming that about 80% of all network programming problems have nothing to do with network programming, per se. That is, the problems are not with the API functions such as accept and select, but the problems arise from a lack of understanding of the underlying network protocols. For example, I have found that once a student understands TCP’s three-way handshake and four-packet connection termination, many network programming problems are immediately understood.

下面是我的 remix。

TCP 的三路握手

肯定是客户端先表白。

  1. 客户端对服务器:我要和你发展关系。(#1,SYN)
  2. 服务器对客户端:你可以和我发展关系。(#2,SYN,ACK)
  3. 客户端对服务器:在一起~(#3,ACK)

于是三次握手后,他们在一起了(连接建立了)。

TCP 的四次挥手

可以是客户端说分手,也可以是客户端。这里以客户端作为负心汉。

  1. 客户端对服务器:恋爱谈完了,我们分手把。(#1,FIN)
  2. 服务器对客户端:可以的。(如果还有财务纠纷那就先还钱,不让分手的。)(#2,ACK)
  3. 服务器对客户端:那就分。(#3,FIN)
  4. 客户端对服务器:恩。(#4,ACK)
计算机网络 · GitBook @
HTTP @

HTTP 的特性 - HTTP构建于TCP/IP协议之上,默认端口号是80 - HTTP是无连接无状态的

  • 幂等的意味着对同一URL的多个请求应该返回同样的结果。
  • 在 HTTP 1.1 版本中,默认情况下所有连接都被保持,如果加入 “Connection: close” 才关闭。目前大部分浏览器都使用 HTTP 1.1 协议,也就是说默认都会发起 Keep-Alive 的连接请求了,所以是否能完成一个完整的 Keep-Alive 连接就看服务器设置情况。
TCP @

TCP 的特性

  • TCP提供一种面向连接的、可靠的字节流服务
  • 在一个TCP连接中,仅有两方进行彼此通信。广播和多播不能用于TCP
  • TCP使用校验和,确认和重传机制来保证可靠传输
  • TCP使用累积确认
  • TCP使用滑动窗口机制来实现流量控制,通过动态改变窗口的大小进行拥塞控制
Socket @
  • Socket 起源于 Unix ,Unix/Linux 基本哲学之一就是“一切皆文件”,都可以用“ 打开(open) –> 读写(write/read) –> 关闭(close)”模式来进行操作。因此 Socket也被处理为一种特殊的文件。
二叉树 @

二叉树:二叉树是有限个结点的集合,这个集合或者是空集,或者是由一个根结点和两株互不相交的二叉树组成,其中一株叫根的做左子树,另一棵叫做根的右子树。

二叉树的性质:

  • 性质1:在二叉树中第 i 层的结点数最多为2^(i-1)(i ≥ 1)
  • 性质2:高度为k的二叉树其结点总数最多为2^k-1( k ≥ 1)
  • 性质3:对任意的非空二叉树 T ,如果叶结点的个数为 n0,而其度为 2 的结点数为 n2,则:n0 = n2 + 1

满二叉树:深度为k且有2^k -1个结点的二叉树称为满二叉树

完全二叉树:深度为 k 的,有n个结点的二叉树,当且仅当其每个结点都与深度为 k 的满二叉树中编号从 1 至 n 的结点一一对应,称之为完全二叉树。(除最后一层外,每一层上的节点数均达到最大值;在最后一层上只缺少右边的若干结点)

性质4:具有 n 个结点的完全二叉树的深度为 log2n + 1

注意:仅有前序和后序遍历,不能确定一个二叉树,必须有中序遍历的结果

平衡二叉树 @

平衡二叉树(balanced binary tree),又称 AVL 树。它或者是一棵空树,或者是具有如下性质的二叉树:

  • 它的左子树和右子树都是平衡二叉树,
  • 左子树和右子树的深度之差的绝对值不超过1。

平衡二叉树是对二叉搜索树(又称为二叉排序树)的一种改进。二叉搜索树有一个缺点就是,树的结构是无法预料的,随意性很大,它只与节点的值和插入的顺序有关系,往往得到的是一个不平衡的二叉树。在最坏的情况下,可能得到的是一个单支二叉树,其高度和节点数相同,相当于一个单链表,对其正常的时间复杂度有O(log(n))变成了O(n),从而丧失了二叉排序树的一些应该有的优点。

B-树 @

B-树:B-树是一种非二叉的查找树, 除了要满足查找树的特性,还要满足以下结构特性:

一棵 m 阶的B-树:

  • 树的根或者是一片叶子(一个节点的树),或者其儿子数在 2 和 m 之间。
  • 除根外,所有的非叶子结点的孩子数在 m/2 和 m 之间。
  • 所有的叶子结点都在相同的深度。

B-树的平均深度为logm/2(N)。执行查找的平均时间为O(logm);

Trie 树 @

Trie 树,又称前缀树,字典树, 是一种有序树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。

Trie 树查询和插入时间复杂度都是 O(n),是一种以空间换时间的方法。当节点树较多的时候,Trie 树占用的内存会很大。

Trie 树常用于搜索提示。如当输入一个网址,可以自动搜索出可能的选择。当没有完全匹配的搜索结果,可以返回前缀最相似的可能。

哈希表 @
冲突解决 @
  • 链地址法

    链地址法的基本思想是,为每个 Hash 值建立一个单链表,当发生冲突时,将记录插入到链表中。

  • 开放地址法

http://open.163.com/movie/2010/12/1/S/M6UTT5U0I_M6V2U3R1S.html

比如数字0x12345678在两种不同字节序CPU中的存储顺序如下所示:

Big Endian

    低地址                                            高地址
    ---------------------------------------------------->
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |     12     |      34    |     56      |     78    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Little Endian

    低地址                                            高地址
    ---------------------------------------------------->
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |     78     |      56    |     34      |     12    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
union test {
    short  i;
    char str[sizeof(short)];
} tt;

void main()
{
    tt.i = 0x0102;
    if(sizeof(short) == 2)
        {
            if(tt.str == 1 && tt.str == 2)
                printf("大端字节序");
            else if(tt.str = 2 && tt.str == 1)
                printf("小端字节序");
            else
                printf("结果未知");
         }
    else
        printf("sizof(short)=%d,不等于2",sizeof(short));
}
qiu-deqing/FE-interview: 收集的前端面试题和答案 @

HTTP method

  • 一台服务器要与HTTP1.1兼容,只要为资源实现GET和HEAD方法即可
  • GET是最常用的方法,通常用于请求服务器发送某个资源。
  • HEAD与GET类似,但服务器在响应中值返回首部,不返回实体的主体部分
  • PUT让服务器用请求的主体部分来创建一个由所请求的URL命名的新文档,或者,如果那个URL已经存在的话,就用干这个主体替代它
  • POST起初是用来向服务器输入数据的。实际上,通常会用它来支持HTML的表单。表单中填好的数据通常会被送给服务器,然后由服务器将其发送到要去的地方。
  • TRACE会在目的服务器端发起一个环回诊断,最后一站的服务器会弹回一个TRACE 响应并在响应主体中携带它收到的原始请求报文。TRACE方法主要用于诊断,用于验证请求是否如愿穿过了请求/响应链。
  • OPTIONS方法请求web服务器告知其支持的各种功能。可以查询服务器支持哪些方法或者对某些特殊资源支持哪些方法。
  • DELETE请求服务器删除请求URL指定的资源
css sprite是什么,有什么优缺点

概念:将多个小图片拼接到一个图片中。通过background-position和元素尺寸调节需要显示的背景图案。

优点:

  • 减少HTTP请求数,极大地提高页面加载速度
  • 增加图片信息重复度,提高压缩比,减少图片大小
  • 更换风格方便,只需在一张或几张图片上修改颜色或样式即可实现

缺点:

  • 图片合并麻烦
  • 维护麻烦,修改一个图片可能需要从新布局整个图片,样式

refs and see also

为什么在 CPU 中要用 Cache 从内存中快速提取数据? - 知乎 @

既然CPU速率高, 内存速率慢,那么中间加一个Cache的目的就是为了让存储体系可以跟上CPU的速度.

普通的CPU+DRAM内存的结构, 如果没有设计Cache, 每一次CPU都要找内存要数据, 这个延迟估计在80个时钟周期左右. 这是因为CPU要从内部运算核心将请求发到CPU边缘的总线上, 从总线上电路板, 到达北桥, 再上电路板到达DRAM. DRAM搜索到数据后如此再送回去. CPU动作那么快, 等的黄花菜都凉了.如果加了Cache会怎样? L1 Cache, 访问延迟在4个周期左右, L2 Cache, 延迟在15个周期左右, L3Cache, 延迟在50个周期左右. 但是由于添加了很多Cache, CPU访问内存的速度被降低了, 需要120个周期左右. 如果CPU需要的内容, 90%在L1 Cache里有, 6%在L2 Cache里有, 3%在L3 Cache里有, 1%要去找DRAM拿. 那么整个存储体系的等效延迟就是: 7.2个时钟周期.这不是爽歪了么??

预先读取,为什么cpu不能做呢?预取(prefetch)这件事cpu的确不做, 是Cache在做, 每一集的Cache都会有自己的 prefetcher. 而实际上L1 Cache已经被融合进CPU内部里了, L1I和L1D和CPU流水线简直就是紧挨在一起, L2 Cache又紧挨着CPU的L1D. 所以L1I, L1D, L2它们做预取, 和 CPU自己做是一回事! 而且CPU跑多快, 预取的速度就有多快! 上面凭什么说“CPU需要的内容, 90%在L1 Cache里有, 6%在L2 Cache里有”? 就是因为Cache中数据大多是复用的, 而且Cache基于历史数据还一直在预取! 而CPU和prefetcher像极了老总和小秘的关系, 比如:

在校学生一枚,面对高性能服务器开发、分布式系统、缓存系统等等。该如何最快最好的提升自己的技术水平呢? - 知乎 @

作为学生的你,你现在学习的 算法、数据结构、网络原理、操作系统、组件原理、汇编语言 等等科目,是内功!内功需要按顺序,循序渐进地学习,而且学习过程非常痛苦且艰难!那些招式与内功相比,算个球!

HTTP 协议入门 - 阮一峰的网络日志 @

HTTP 是基于 TCP/IP 协议的应用层协议。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口。

最早版本是1991年发布的0.9版。该版本极其简单,只有一个命令GET。

1996年5月,HTTP/1.0 版本发布,内容大大增加。

首先,任何格式的内容都可以发送。这使得互联网不仅可以传输文字,还能传输图像、视频、二进制文件。这为互联网的大发展奠定了基础。

其次,除了GET命令,还引入了POST命令和HEAD命令,丰富了浏览器与服务器的互动手段。

再次,HTTP请求和回应的格式也变了。除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。

其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。

Content-Type 字段

关于字符的编码,1.0版规定,头信息必须是 ASCII 码,后面的数据可以是任何格式。因此,服务器回应的时候,必须告诉客户端,数据是什么格式,这就是 Content-Type字段的作用。

下面是一些常见的Content-Type字段的值。

text/plain                  audio/mp4
text/html                   video/mp4
text/css                    application/pdf
image/jpeg                  application/zip
image/png                   application/atom+xml
image/svg+xml               application/javascript

MIME type还可以在尾部使用分号,添加参数: Content-Type: text/html; charset=utf-8

HTTP/1.0 版的主要缺点是,每个TCP连接只能发送一个请求。发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。

TCP连接的新建成本很高,因为需要客户端和服务器三次握手,并且开始时发送速率较慢(slow start)。所以,HTTP 1.0版本的性能比较差。随着网页加载的外部资源越来越多,这个问题就愈发突出了。

1997年1月,HTTP/1.1 版本发布,只比 1.0 版本晚了半年。它进一步完善了 HTTP 协议,一直用到了20年后的今天,直到现在还是最流行的版本。

1.1 版的最大变化,就是引入了持久连接(persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。

客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接。

目前,对于同一个域名,大多数浏览器允许同时建立6个持久连接。

2009年,谷歌公开了自行研发的 SPDY 协议,主要解决 HTTP/1.1 效率不高的问题。

这个协议在Chrome浏览器上证明可行以后,就被当作 HTTP/2 的基础,主要特性都在 HTTP/2 之中得到继承。

HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送(server push)。

常见场景是客户端请求一个网页,这个网页里面包含很多静态资源。正常情况下,客户端必须收到网页后,解析HTML源码,发现有静态资源,再发出静态资源请求。其实,服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了。

浅谈字节序(Byte Order)及其相关操作 - Jeffrey Zhao - 博客园 @

对于我们常用的CPU架构,如Intel,AMD的CPU使用的都是小字节序,而例如Mac OS以前所使用的Power PC使用的便是大字节序(不过现在Mac OS也使用Intel的CPU了)。此外,除了大字节序和小字节序之外,还有一种很少见的中字节序(middle endian),它会以2143的方式来保存数据(相对于大字节序的1234及小字节序的4321)。

??? network???

定点数与浮点数

Master-1.注重实效的哲学 | PaddingMe’s Blog

你的字典里有多少元素? - 老赵点滴 - 追求编程之美 @

“字典”或者说“哈希表”大家都会用,这真是一个好东西,只要创建了之后就可以不断的丢东西进去,添加删除都是O(1)操作,那叫一个快字了得。不过这里我要再次引用 Alan Perlis 的名言:

Lisp programmers know the value of everything but the cost of nothing.

目的是想提醒做事“不要忘记背后的代价”。

《写给大家看的设计书》读书笔记 | PaddingMe’s Blog @

约书亚树

一旦你能够说出什么东西的名字,就会很容易注意到它。你就会掌握它,拥有它,使它在你的控制中。

TCP使用滑动窗口机制来实现流量控制,通过动态改变窗口的大小进行拥塞控制

TODO?

Code point - Wikipedia, the free encyclopedia

refs and see also

boost bind 源码剖析 - coredump - SegmentFault

leveldb源码分析(1)--arena内存池的实现 - redteam - SegmentFault

STL区间成员函数及区间算法总结 - 大CC - SegmentFault

《Effective C++》 - mikey219 - SegmentFault

二叉排序树实现(C++封装) - zhoutk - SegmentFault

位运算 - 人工智能之路 - SegmentFault

快速了解C/C++的左值和右值 - JK - SegmentFault

Stack Overflow - 话题精华 - 知乎

Identicon - Wikipedia, the free encyclopedia

Morse code - Wikipedia, the free encyclopedia

所以, 倾情推荐:

http://oj.leetcode.com LeetCode Online Judge

只要每道题都可以保证 3 遍以内过, 所有湾区工作 entry level 随便挑. 涉及到的基本都是 Linked List, DP, BST 这样的简单数据结构或者算法题.

你人还是不够聪明,这个问题一出来你就应该知道他背诵的版本是 hash 啦。。。你应该顺着他说 hash,这不是开玩笑。


Big O notation - Wikipedia, the free encyclopedia

Cayley’s formula - Wikipedia, the free encyclopedia

为什么交通信号灯需要红绿两色?

软件测试 - 话题精华 - 知乎 @

软件测试就是利用测试工具按照测试方案和流程对产品进行功能和性能测试,甚至根据需要编写不同的测试工具,设计和维护测试系统,对测试方案可能出现的问题进行分析和评估。执行测试用例后,需要跟踪故障,以确保开发的产品适合需求。

冒烟测试_百度百科 @

这一术语源自硬件行业。对一个硬件或硬件组件进行更改或修复后,直接给设备加电。如果没有冒烟,则该组件就通过了测试。在软件中,“冒烟测试”这一术语描述的是在将代码更改嵌入到产品的源树中之前对这些更改进行验证的过程。在检查了代码后,冒烟测试是确定和修复软件缺陷的最经济有效的方法。冒烟测试设计用于确认代码中的更改会按预期运行,且不会破坏整个版本的稳定性。

In computer programming and software testing, smoke testing (also confidence testing, sanity testing) is preliminary testing to reveal simple failures severe enough to (for example) reject a prospective software release. A smoke tester will select and run a subset of test cases that cover the most important functionality of a component or system, to ascertain if crucial functions of the software work correctly.:37 When used to determine if a computer program should be subjected to further, more fine-grained testing, a smoke test may be called an intake test.

sanity,['sænəti],n. 明智;头脑清楚;精神健全;通情达理

For example, a smoke test may address basic questions like “Does the program run?”, “Does it open a window?”, or “Does clicking the main button do anything?” The process of smoke testing aims to determine whether the application is so badly broken as to make further immediate testing unnecessary. As the book Lessons Learned in Software Testing puts it, “smoke tests broadly cover product features in a limited time … if key features don’t work or if key bugs haven’t yet been fixed, your team won’t waste further time installing or testing”.

Smoke tests frequently run quickly, often in the order of a few minutes, giving the benefit of quicker feedback and faster turnaround than the running of full test suites, which can take hours – or even days.

refs and see also

是的,我想说,他妈的没接触到技术性的东西你不会自己去接触啊,

都二十好几的人了,还在等人把东西嚼碎了喂你嘴里????????

目前国内 QA 的工作面很广。web 上点鼠标的是 QA,linux 上写脚本的是 QA,编写单元测试的是 QA,负责工具开发的是 QA,推广 TDD 或者敏捷的也是 QA。

根据 QA 的工作类型区分前途是比较合适的。

  • 黑盒测试工程师

  • 自动化测试工程师 @

    使用 qtp,selenium,watir,或者是其他的技术框架来自动化测试工作的。在 unix 上做自动化工作的,比如编写 shell 脚本,或者其他的脚本,也是属于此类。

    因为自动化在回归阶段可以节省人力,可以有效的对产品的质量进行度量,并且可以不断的累积,结合覆盖率统计,或者需求覆盖统计等手段,可以很好的保证产品线的开发质量。所以自动化是很重要的技术。大公司一般都有这样的工作和人员配备。

    不过前端的自动化,和后端的自动化,仍旧有一些弊病。很多公司倾向于使用分层自动化去解决不同层面的质量问题。这部分相对有点技术含量,大公司招人,也是必考的内容。相对来说,有点前途。但是一旦自动化方案稳定了,那么这类人也会面临职业发展困境。只不过目前自动化仍然在不断发展,这个问题暴露的不是很隐蔽。这个领域的工程师将来会两极分化,一部分转向自动化工具的研发,一部分转向自动化case的维护。

  • 白盒测试工程师 @

    这部分人主要做代码分析,审核,编写必要的单元测试,并关注代码的各种覆盖率情况。

  • 测试架构师 @

    负责规划辅助测试的各种工具和平台。基本上是全能的。并能对自动化,技术改进和测试理论有很好的贡献。属于大牛级别。比如研究封装开源的框架,或者开发新技术,来提高 QA 的测试效率和保证质量覆盖。 不过这个职位将来会比较尴尬,可能会并到测试工具开发工程师中,或者在对应的工具开发团队担任管理。这个职位,将来会死掉。企业不需要太多的 title。

  • 性能测试工程师 @

    国内的黄金职业,技术相对专业,但是精通了基本可以一劳永逸。性能测试的理论基本跟开发技术关联不大,所以还是很稳当的。

  • 安全测试工程师 @

    严格来说不算 QA,虽然 QA 里面有做这个的,但是专业理论要求较高,跟开发技术的关联性也不是太大,具备通用性,所以也是很黄金的。

  • 测试管理 @

    去做 QA 的管理角色,比如带项目,QA 数据统计和分析。带团队等。自然也是很黄金的了。

对于大部分公司来说,职位并不是严格的,很多人可能是一职多能。

发展方向主要有以下几种

  1. 走 QA 技术路线,测试分析,自动化,白盒,或者专心走性能测试,安全测试,测试规划等。
  2. 走 RD 技术路线,转行做研发。这个例子也很多。开发肯定比 QA 更可靠。 已经有不少先例了。
  3. 走管理路线。有管理爱好的,可以往这个方向发展。
  4. 走业务路线。去做产品经理,规划产品设计。也是蛮不错的职位。
  5. 开发测试工具,测试解决方案,提供测试服务。类似于 51testing 和博为峰这样的公司。

为什么微软叫 SDET 而不是 QA?Software Development Engineer in Test,SDET 中文叫:软件测试开发工程师。主体还是 SDE,做的还是软件开发,只不过偏测试方面的开发。这个不是专职的测试。Google、Amazon 中也有 SDET,但是大家都知道,真正能保证软件质量的还是开发团队自己。

你需要很清楚的明白一点,对于任何一个公司,如果“产出性”的人多于“支持性”的人,那么这个公司是往上走的,如果“支持性”的人多于“产出性”的人,那么这个公司一定处于下坡路上。所谓“产出性”还是“支持性”,就看你的团队或是你的部门是“财务中心 Finical Center”还是一个“成本中心 Cost Center”了。

1 个好的工程师顶 10-100 个烂的工程师,1 个烂的工程师,可以很容易地创造 2-10 个工作机会。

软件测试的魅力何在?您为什么选择测试一行而不做开发? @

  你让一场本该在用户面前发生的灾难,提前在自己面前发生了
  会让你有一种救世主的感觉
  拯救了这个用户,也拯救了这个软件,避免了他被卸载的命运

  再进一步,你还改变了你的程序员兄弟被骂娘的命运
  你改变了你的老板破产的命运
  你改变了你的兄弟们失业的命运
  这大约就是测试的魅力所在

  为什么选择?
  有的人喜欢创造世界,他们做了程序员
  有的人喜欢拯救世界,他们做了测试员

代码是为了什么,当然是为了重复运行。如何保持 unit test 代码的稳定?主要靠好的 API设计。API 切实正确切割了需求,那么在重构的时候 API 就基本不用变化, unit test 也不用重写。以后你重构的时候,只要你的 unit test 覆盖的够好,基本跑一遍就知道有没有改成傻逼。可以节省大量的时间。

所以那些专门写不需要维护的软件的人,讨厌测试,也是情有可原的。

测试指南 - Rei

Memory hierarchy - Wikipedia, the free encyclopedia

:

Typical memory hierarchy (access times and cache sizes are approximations
of typical values used as of 2013 for the purpose of discussion; actual
values and actual numbers of levels in the hierarchy vary):

-   CPU registers (8-256 registers)
      ~ immediate access, with the speed of the inner most core of the processor
-   L1 CPU caches (32 KiB to 512 KiB)
      ~ fast access, with the speed of the inner most memory bus owned exclusively by each core
-   L2 CPU caches (128 KiB to 24 MiB)
      ~ slightly slower access, with the speed of the memory bus shared between twins of cores
-   L3 CPU caches (2 MiB to 32 MiB)
      ~ even slower access, with the speed of the memory bus shared between
        even more cores of the same processor
-   Main physical memory (RAM) (256 MiB to 64 GiB)
      ~ slow access, the speed of which is limited by the spatial distances
        and general hardware interfaces between the processor and the memory
        modules on the motherboard
-   Disk (virtual memory, file system) (1 GiB to 256 TiB)
      ~ very slow, due to the narrower (in bit width), physically much
        longer data channel between the main board of the computer and the
        disk devices, and due to the extraneous software protocol needed on
        the top of the slow hardware interface
-   Remote Memory (such as other computers or the Internet) (Practically unlimited)
      ~ speed varies from very slow to extremely slow
写给准备参加秋招的学弟学妹们一定要来看哦 - 671coder 的专栏 - 博客频道 - CSDN.NET

操作系统很重要吧,这个就不用说了,需要看的内容非常简单。大家把何昊老师出的《程序员面试笔试宝典》这本书第八章到第十章全都看一遍就可以了,计算机网络 9.1、 9.3、9.4 是重点,操作系统部分 10.1 和 10.2 是重点,对于数据库,可能只需要记得简单的语句就行了,然后范式、一些锁、主键外键、索引看一看记住就可以,事物是非常重要的,必须掌握。

C++ 是个好东西,需要准备的东西比较多,推荐看一下《C++ Primer》和《effective c++》想依靠 c++ 为门槛拿到不错的 offer 的话,这两本书打死也要看。最好边看边做笔记,把重点画下来,或者写 blog,我在网上认识一个 sdust 大二的大牛 zxf,他整理的 blog 就非常棒,还被评为了 csdn 的专栏达人,链接在此。

2.5 年, 从 0 到阿里 - 翡青的博客 - 博客频道 - CSDN.NET @

我的准备工作大致分为五方面内容: C++, Linux, 数据结构与算法, 计算机网络 (TCP/IP) 和操作系统. 如果一个本科生能够把这五方面的基础打得比较坚实再加上稍稍一点儿运气, 拿下互联网的 offer 是不在话下的, 另外如果你实力够强的话, 那仅需的一点儿运气也是不需要的, 在此我引用 671 学长的一句关于面试的经典: ”面试 = 运气(50-n)/100 + 实力(50+n)/100, n=f(x),x 即实力,n 与 x 成正比关系, 这就意味着: 你实力越强, 对运气的依赖性越低, 所以实力才是非常重要的一个环节.”, 下面分别介绍一下我所准备的五方面内容。

CS 基础 - 翡青的博客 - 博客频道 - CSDN.NET
  • TCP/IP入门(1) –链路层

一面问得问题有: (1)TCP 三次握手过程, 与为啥需要采用三次握手; (2)TCP TIME_WAIT 状态的原因; (3)C++ 虚函数机制 (C++ 对象模型); (4)C++ Static 关键字; (5)Select/Poll/Epoll 的异同 (使用与内部实现方面); (6)C++ 迭代器失效问题 (iterator 原理); (7)map/set 容器的实现原理 (红黑树知识 +STL 容器内部原理);

有道云笔记

线性代数的妙用:怎样在Windows画图软件中实现28度旋转? | Matrix67: The Aha Moments

想学好计算机算法,是否需要重新学数学呢? - 知乎

要学什么,就学什么。

要学算法,就学算法,遇到数学问题,就查,就问,不要分心。

要参加英文面试,就练习英文面试,别背单词,别练阅读,也不用管面试中说不到的话题。

要做什么,就准备什么。宁可简单粗暴,不要曲线救国。摊子铺大了,目标就模糊了,效率低,反馈慢,渐渐的就兜不回来了。

C++ 求余用的“%”有与它效率相同的其它算法吗? - 知乎 @

Grisu 是把浮点数转换为字符串的算法。在 Chrome 里执行这段 JavaScript 实际上就调用了 Grisu:

document.write(1/3); // 0.3333333333333333

在许多书籍也会谈及,当除数为常数时,可以把除法变成乘以除数的倒数。现在的编译器都会自动做这个优化。事实上,在上面的代码里,第二个除法(div /= 10)中的除数(10)就是常数,编译器会自动把它优化成64位乘法及右移指令,例如 clang 在 x86-64 目标下:

refs and see also

Branch table - Wikipedia, the free encyclopedia

In computer programming, a branch table or jump table is a method of transferring program control (branching) to another part of a program (or a different program that may have been dynamically loaded) using a table of branch or jump instructions. It is a form of multiway branch. The branch table construction is commonly used when programming in assembly language but may also be generated by a compiler, especially when implementing an optimized switch statement where known, small ranges are involved with few gaps.

#include <stdio.h>
#include <stdlib.h>

typedef void (*Handler)(void);    /* A pointer to a handler function */

/* The functions */
void func3 (void) { printf( "3\n" ); }
void func2 (void) { printf( "2\n" ); }
void func1 (void) { printf( "1\n" ); }
void func0 (void) { printf( "0\n" ); }

Handler jump_table[4] = {func0, func1, func2, func3};

int main (int argc, char **argv) {
    int value;

    /* Convert first argument to 0-3 integer (modulus) */
    value = ((atoi(argv[1]) % 4) + 4) % 4;

    /* Call appropriate function (func0 thru func3) */
    jump_table[value]();

    return 0;
}
RapidJSON 代码剖析(一):混合任意类型的堆栈 - Milo的编程 - 知乎专栏
bool StartArray() {
    new (stack_.template Push<ValueType>()) ValueType(kArrayType);
    return true;
}

这里其实用了两个可能较少接触的 C++ 特性。第一个是 placement new,第二个是 template disambiguator。

ValueType* v = stack_.Push<ValueType>(); // (1)

这里 Push<ValueType> 是一个 dependent name,它依赖于 ValueType 的实际类型。这里编译器不能确认 < 为小于运算符,还是模板的 <。为了避免歧义,需要加入 template 关键字。这是 C++ 标准的规定,缺少这个 template 关键字 gcc 和 clang 都会报错,而 vc 则会通过(C++ 标准也容许实现这样的编译器)。和这个语法相近的还有 typename disambiguator。

class Stack {
    Stack(Allocator* allocator, size_t stackCapacity);
    ~Stack();
    void Clear();
    void ShrinkToFit();
    template<typename T> T* Push(size_t count = 1);
    template<typename T> T* Pop(size_t count);
    template<typename T> T* Top();
    template<typename T> T* Bottom();
    Allocator& GetAllocator();
    bool Empty() const;
    size_t GetSize();
    size_t GetCapacity();
};
Stack s;
*s.Push<int>() = 1;
*s.Push<int>() = 2;
*s.Push<int>() = 3;
*s.Push<int>() = 4;
for (int i = 0; i < 2; i++) {
    int* a = s.Pop<int>(2);
    std::cout << a[0] << " " << a[1] << std::endl;
}
// 输出:
// 3 4
// 1 2

<>读书笔记(三) - zyfforlinux - 博客频道 - CSDN.NET

pocoproject/poco: POCO C++ Libraries - Cross-platform C++ libraries with a network/internet focus.

【报告】神经网络:技术发展与未来挑战(PDF下载)

统计 n! 中 0 的个数 - jxlincong 的专栏 - 博客频道 - CSDN.NET

1024 的阶乘末尾有多少个 0,这个问题只要理清思想就很好解了。

有多少个 0 取决于有多少个 10 相乘,即 1024 拆成小单元后有多少个 10。由于 10 不是素数,所以直接用 10 进行计算的话会有很多问题,于是将 10 分解。

10 可以分解成 2x5,2 和 5 都是素数,由于每 2 个相邻的数中一定包含 2,所以只要计算出有多少个 5 就可以了(2 会在 5 之后及时出现)。

于是解法如下:

  • 是 5 的倍数的数有:1024 /5 = 204 个(说明 1024! 的展开式中的数,因式分解的因子中,至少有 1 个含有 5 的个数)
  • 是 25 的倍数的数有:1024/ 25 = 40 个(1024! 的展开式中的数,因式分解的因子中,至少有 2 个含有 5 的个数)
  • 是 125 的倍数的数有:1024/ 125 = 8 个(1024! 的展开式中的数,因式分解的因子中,至少有 3 个含有 5 的个数)
  • 是 625 的倍数的数有:1024/ 625 = 1 个(1024! 的展开式中的数,因式分解的因子中,至少有 4 个含有 5 的个数)

所以 1024! 中总共有 204+40+8+1=253 个因子 5。即 1024!后有 253 个 0

算题思想:

  • (1)先找出有 1 个 5 的数
  • (2)然后找出有两个 5 的,2 个 5 的数虽然在第一步算过了,但是两个中剩下的那个 5 还可以形成 0
  • (3)之后就是找出有 3 个 5 的,4 个 5 的,直到 n 个 5(5 的 n 次方小于阶乘的数)
心智工具箱(4):执行意图 - 阳志平的网志 @

Peter Gollwitzer - Wikipedia, the free encyclopedia

Peter Gollwitzer

(●—●) | 技术面之项目面试技巧大揭秘_牛客网 @

为什么项目经历差不多,大家的面试分数差别很多?面试官问项目时都在考察什么?在项目经验弱的情况下,应届生应该如何回答面试官的问题,更能引导面试节奏,让面试官更有参与感?

做项目

  • 语言/框架
  • 工具
  • 协议/模式
  • 产品/职位

在上面填上自己的内容!

几个可以在叙述中强调的点:

  • 难度
  • 造轮子
  • 兴趣
  • 创新

有没有人带?

如何找资料?

如何管理进度?

如何协调其他成员?

核心难点和结果?

扩展和深入?

面试官的关注点:

  • 能力
    • 你了解哪些部分
    • 你深入了解哪些
    • 你横向了解哪些
  • 潜力
    • 你怎么解决问题
    • 你如何举一反三
    • 你怎么优化项目
    • 你如何快速学习

你的博客?如何搭建的?

注意,不要夸夸其谈。要真诚、有理有据。

冒泡 答过的问题 - 知乎 @

第二个是二分查找算法的面试,由于面试很容易出这个题,这题很大难点又是在于二分到最后的边界判断,所以给人出了这么个主意:

while start < end:
    if end - start < 5:
        #顺序搜索
    else:
        mid = (start + end) / 2
        #二分,略

恩,就是问题规模小于一定量就改顺序查找,也是 O(lgN),而且保证不会写错,如果面试官问还可以跟他扯,说 5 个元素顺序 search 的话 cache 友好之类的,说不定就忽悠成功啦

如何区别 fly 这个词是指飞行还是苍蝇?脱离具体场景并无意义,所以得看你这 32 个 1 是做有符号数补码还是无符号数补码解释

具体到题主这个问题,这样理解比较好,先不考虑具体存储限制:

  补码,-1 是……111111111111111111111111111111111(32 个 1 前导无限个 1)
  而 4294967295 是……011111111111111111111111111111111(32 个 1 前导无限个 0)
  但是,计算机中存数字,只能存有限位数,所以有符号 32 位整数用最前面的位表示前导是无限个 1 还是无限个 0,表示范围是 -231~231-1
  而无符号数默认是前导无限个 0,所以 32 位无符号整数表示范围是 0~2^32-1

为什么同样是解决一个问题,别人就能想出算法,而我却绞尽脑汁,百般尝试也不得其法? - 知乎 @

能上大学,大家智商之间都没有多大差距,关键字在于态度。他们问我的这些问题我都碰到过,所以我可以一秒指出问题。练习越多,经验越丰富。层次越高,看问题越明白。这都是大量的代码和阅读堆出来的。

为什么同样是解决一个问题,别人就能想出算法,而我却绞尽脑汁,百般尝试也不得其法?

为啥我就能三分钟解决而你要三十分钟?

无他,唯手熟尔。

记得早年学习 window 编程时,都推荐 windows 核心编程,于是买了本研究,发现好难,很难读的下去。后来读完了 windows 程序设计上下册,回过头来再看,发现又好简单。

这种情况多半是你的知识体系不完善,本身学识和经验就跟别人差好多。表现出来好像是别人比你聪明,但很多时候并不是这样。

知识量不够,想法自然受到局限。经验不够难免要采坑。一步一步提升自己才是正经事儿。

(●—●) | 牛客网 @
  • (●—●) | 用不带头结点的单链表存储队列,其队头指针指向队头结点,队尾指针指向队尾结点,则在进行出队操作时()_牛客网 @

    当队列中只有一个元素时,出队后需要清空对头和队尾指针。

  • (●—●) | 以下与数据的存储结构无关的术语是()_牛客网 @

    栈可以是顺序存储,也可以是链式存储,与存储结构无关。循环队列是队列的顺序存储结构,链表是线性表的链式存储结构,用散列法存储的线性表叫散列表,都与存储结构有关

    存储结构是数据的逻辑结构用计算机语言的实现,常见的存储结构有: 顺序存储,链式存储 , 索引存储 ,以及 散列存储 。其中散列所形成的存储结构叫 散列表(又叫哈希表) ,因此哈希表也是一种存储结构。栈只是一种抽象数据类型,是一种逻辑结构,栈逻辑结构对应的顺序存储结构为顺序栈,对应的链式存储结构为链栈,循环队列是顺序存储结构,链表是线性表的链式存储结构

  • (●—●) | integer-to-roman_leetcode笔试题_牛客网 @
    class Solution {
    public:
        string intToRoman(int num) {
            static const char *x[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" };
            static const char *x0[] = { "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC" };
            static const char *x00[] = { "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM" };
            static const char *x000[] = { "M", "MM", "MMM" };
    
            if( num >= 1000 ) {
                return string(x000[num/1000-1]) + intToRoman(num%1000);
            } else if( num >= 100 ) {
                return string(x00[num/100-1]) + intToRoman(num%100);
            } else if( num >= 10 ) {
                return string(x0[num/10-1]) + intToRoman(num%10);
            } else if( num >= 1 ) {
                return string(x[num-1]);
            }
    
            return string(); // num == 0
        }
    };
    string result;
    while( num != 0 ) {
        if( num >= 1000 ) {
            result += string(x000[num/1000-1]);
            num %= 1000;
        } else if( num >= 100 ) {
            result += string(x00[num/100-1]);
            num %= 100;
        } else if( num >= 10 ) {
            result += string(x0[num/10-1]);
            num %= 10;
        } else if( num >= 1 ) {
            result += string(x[num-1]);
            break;
        }
    }
    
    return result;
  • (●—●) | minimum-depth-of-binary-tree_牛客网 @
    class Solution {
    public:
        int run(TreeNode *root) {
            return minDepth( root, false );
        }
    private:
        int minDepth( TreeNode *root, bool hasbrother ) {
            if( !root ) { return hasbrother ? INT_MAX : 0; }
            return 1 + min( minDepth( root->left, root->right ),
                            minDepth( root->right, root->left ) );
        }
    };
  • (●—●) | (●—●) | 类A是类B的友元,类C是类A的公有派生类,忽略特殊情况则下列说法正确的是()_牛客网 @

    类 A 是类 B 的友元, 类 C 是类 A 的公有派生类, 忽略特殊情况则下列说法正确的是 ()

    • 类 B 是类 A 的友元
    • 类 C 不是类 B 的友元
    • 类 C 是类 B 的友元
    • 类 B 不是类 A 的友元

    BD

      友元关系是单向的,不是对称,不能传递。
      关于传递性,有人比喻:父亲的朋友不一定是儿子的朋友。
      那关于对称性,是不是:他把她当朋友,她却不把他当朋友?✧(≖ ◡ ≖✿)

  • (●—●) | evaluate-reverse-polish-notation_leetcode笔试题_牛客网

  • (●—●) | max-points-on-a-line_leetcode笔试题_牛客网

  • (●—●) | 顺时针打印矩阵_牛客网 @
    #include <iostream>
    #include <algorithm>
    #include <iterator>
    #include <vector>
    using namespace std;
    
    class Solution {
    public:
        vector<int> printMatrix(vector<vector<int> > &matrix) {
            int row = matrix.size(), col = matrix[0].size();
            int lr = col, ud = row-1;
            vector<int> ret( row*col );
            int i = 0, j = -1, k = 0;
            while( k < row*col ) {
                if( lr > 0 && k < row*col ) { for( int m = 0; m < lr; ++m ) { ret[k++] = matrix[i][++j]; } --lr; } // right
                if( ud > 0 && k < row*col ) { for( int m = 0; m < ud; ++m ) { ret[k++] = matrix[++i][j]; } --ud; } // down
                if( lr > 0 && k < row*col ) { for( int m = 0; m < lr; ++m ) { ret[k++] = matrix[i][--j]; } --lr; } // left
                if( ud > 0 && k < row*col ) { for( int m = 0; m < ud; ++m ) { ret[k++] = matrix[--i][j]; } --ud; } // up
            }
            return ret;
        }
    };
    
    int main() {
        vector<vector<int> > matrix = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 16}
        };
        Solution sol;
        vector<int> ret = sol.printMatrix( matrix );
        copy( ret.begin(), ret.end(), ostream_iterator<int>(cout, " ")); puts("");
    }
Learn X in Y Minutes @

nice.

@include <-include/learnxinyminutes.md=

Words @
  • Augusta Ada Byron
  • Alonzo Church: 由人类或任何机器执行操纵符号的任何算法过程,都是可以由某个 TM 执行;
  • SEEEEEEEEmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
     |-  8 -||------------- 32 -------------|
  • regularity, 一致性
  • subordinant class / superclass
  • class hierarchy

    System.out
          .err
          .exit

  1. Control + R, =, pow(2,31)

  2. The SI prefixes (metric prefix) are standardized for use in the International System of Units (SI) by the International Bureau of Weights and Measures (BIPM) in resolutions dating from 1960 to 1991.

  3. IEC 80000-13:2008 is an international standard that defines quantities and units used in information science, and specifies names and symbols for these quantities and units. The standard is published by the International Electrotechnical Commission (IEC) and is part of the group of standards called ISO/IEC 80000, published jointly by the IEC and the International Organization for Standardization (ISO).