ARTS 第二周打卡

目录

A: Algorithm,每周至少做一道 Leetcode
R: Review,阅读并点评至少一篇英文文章
T: Tips,学习至少一个技术技巧
S: Share,分享一篇有观点和思考的技术文章

✨ 坚持一个月吃顿火锅儿!✨

第二周(11-30 至 12-06)

A:

题目:多数元素

很容易想到的是排序取中位数,这个是 O(nlog(n)) 的,更好的解决办法是摩尔投票法,即对拼消耗,O(n) 时间复杂度。

class Solution {
    public int majorityElement(int[] nums) {
        int result = nums[0];
        int mod = 1;
        for (int i = 1; i < nums.length; i++) {
            if (result == nums[i]) {
                mod++;
            } else if (--mod == 0) {
                result = nums[i];
                mod = 1;
            }
        }
        return result;
    }
}

题目:搜索二维矩阵 ||

同简单,从二维矩阵的右上角开始找,比目标值大就往左查询,小就往下。

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int i = 0, j = matrix[0].length - 1;
        while (i < matrix.length && j >= 0) {
            int num = matrix[i][j];
            if (num < target) {
                i++;
            } else if (num > target) {
                j--;
            } else {
                return true;
            }
        }
        return false;
    }
}

R:

How to display your Android project dependency graph in your README file

这篇文章讲的是可以在你的 Github README 文件里面展示 Android 项目的依赖关系图。其实核心就是写了一个 Gradle Task,生成了一个 .dot 文件,dot 即图片描述语言,脚本中还涉及把 .dot 文件转化成 png 的操作,用到的是 Graphviz,在安装完这个软件之后,还需要你的 AS 里面安装一个 State Art 插件,然后就可以直接运行该 Task 了。

T:

如何提升 TCP 三次握手的性能?

TCP 是一个可以双向传输的全双工协议,所以需要经过三次握手才能建立连接。三次握手在一个 HTTP 请求中的平均时间占比在 10% 以上,在网络状况不佳、高并发或者遭遇 SYN 泛洪攻击等场景中,如果不能正确的调整三次握手中的参数,就会对性能有很大的影响。

首先看客户端的优化,客户端在发出 SYN 报文后但没有收到对端 ACK 时,客户端会重发 SYN,重试的次数由 tcp_syn_retries 参数控制,默认是 6 次:

net.ipv4.tcp_syn_retries = 6

第 1 次重试发生在 1 秒钟后,接着会以翻倍的方式在第 2、4、8、16、32 秒共做 6 次重试,最后一次重试会等待 64 秒,如果仍然没有返回 ACK,才会终止三次握手。所以说总耗时是 127 秒,超过 2 分钟。

如果这是一台有明确任务的服务器,就可以根据网络的稳定性和目标服务器的繁忙程度修改重试次数,调整客户端的三次握手时间上限。比如内网中通讯时,就可以适当调低重试次数,尽快的把错误暴露给应用程序。

再看服务端的优化,服务端在收到 SYN 报文并回复 SYN+ACK 时,此时服务端会把该连接信息放入一个 SYN 版连接队列里面,当这个队列溢出时,服务端将无法在建立新的连接。所以此时可以修改 SYN 半连接队列的大小的,即:

net.ipv4.tcp_max_syn_backlog = 1024

如果 SYN 半连接队列已满,只能丢弃连接吗?并不是这样,开启 syncookies 功能就可以在不使用 SYN 队列的情况下成功建立连接。syncoookie 是这么做的:服务端根据当前状态计算出一个值,放在已方发出的 SYN+ACK 报文中发出,当客户端返回 ACK 报文时,取出该值验证,如果合法,就认为连接建立成功。

Linux 下怎样开启 syncookies 功能呢?修改 top_syncookies 参数即可,其中值为 0 时表示关闭该功能,2 表示无条件开启功能,而 1 则表示仅当 SYN 半连接队列放不下时再启用它。由于 syncookie 仅用于应对 SYN 泛洪攻击,这种方式建立的连接,许多 TCP 特性都无法使用,所以,应当把 tcp_syncookies 设置为 1,仅在队列满时再启用:

net.ipv4.tcp_syncookies = 1

当服务端发送完 SYN+ACK 报文后,但是却为收到对端 ACK,这时候服务端就会重发 SYN+ACK。当网络繁忙、不稳定时,报文丢失就会变严重,此时应该调大重发次数,反之则可以调小重发次数。对应的参数如下:

net.ipv4.tcp_synack_retries = 5

当服务端收到 ACK 后,内核就会把连接从 SYN 半连接队列中移除,再移入 accept 队列,等待进程调用 accept 函数时再把连接取出来。如果进程不能及时的调用 accept 函数,就会造成 accept 队列溢出,最终导致建立好的 TCP 连接被丢弃。

实际上,丢弃连接只是 Linux 的默认行为,我们还可以选择向客户端发送 RST 复位报文,告诉客户端连接已经建立失败。打开这一功能需要将 tcp_abort_on_overflow 参数设置为 1。

不过通常情况下,应该把该参数设置为 0,因为这样更有利于应对突发流量。

net.ipv4.tcp_abort_on_overflow = 0

举个例子,当 accept 队列满导致服务端丢掉了 ACK,与此同时,客户端的连接状态却是 ESTABLISHED,进程就会在建立好的连接上发送请求。只要服务端没有为请求回复 ACK,请求就会被多次重发。如果服务端上的进程只有短暂的繁忙导致 accept 队列满,那么当 accept 队列有空位时,再次接收到的请求由于含有 ACK,仍然会触发服务端成功建立连接。所以 tcp_abort_on_overflow 设为 0 可以提高连接建立的成功率,只有你非常肯定 accept 队列会长期溢出,才能设置为 1 以尽快通知客户端。

TFO 技术如何绕过三次握手?

TFO 即 TCP Fast Open,客户端可以在首个 SYN 报文中就携带请求,这节省了 1 个 RTT 的时间。TFO 具体是如何实现的呢?

为了让客户端在 SYN 报文中携带请求数据,必须解决服务端的信任问题。因为此时服务端的 SYN 报文还没有发给客户端,客户端是能够正常建立连接还未可知,但此时服务端需要假定连接已经建立成功,并把请求交付给进程去处理,所以服务端必须能够信任这个客户端。

TFO 到底怎样达成这一目的呢?它把通讯分为两个阶段,第一阶段为首次建立连接,这时走正常的三次握手,但在客户端的 SYN 报文会明确的告诉服务端它想使用 TFO 功能,这样服务端会把客户端 IP 地址用只有自己知道的密钥加密(比如 AES),作为 Cookie 携带在返回的 SYN+ACK 报文中,客户端收到后会将 Cookie 换存在本地。

之后,如果客户端再次向服务端建立连接,就可以在第一个 SYN 报文中携带请求数据,同时还要附带缓存的 Cookie。服务端收到后,会用自己的密钥验证返回 SYN+ACK。虽然客户端收到后还会返回 ACK,但服务器不等收到 ACK 就可以发送 HTTP 相应了,这就减少了握手带来的 1 个 RTT 的时间消耗。

小结一下,如何优化 TCP 的三次握手?我们可以从控制重发次数、调整连接队列的大小、开启 TFO 等思路去着手优化。

S:

How to display your Android project dependency graph in your README file

如何提升 TCP 三次握手的性能

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容