ARTS-week22

Algorithms

Min Stack
思路: 使用两个栈,一个栈用来顺序存储push的数据,另一个用来存出现过的最小值。

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
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/

class MinStack {
public:
/** initialize your data structure here. */
MinStack() {}

void push(int x) {
data.push(x);
if (min_data.empty() || x <= min_data.top()) {
min_data.push(x);
}
}

void pop() {
if (data.top() == min_data.top()) {
min_data.pop();
}
data.pop();
}

int top() {
return data.top();
}

int getMin() {
return min_data.top();
}

private:
stack<int> data, min_data;
};

Intersection of Two Linked Lists
思路: 计算两个链表的长度,从长链表先遍历,当长链表剩余长度和短链表一样时,用两个指针同时遍历两个链表。

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
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {

if (!headA || !headB ) {
return NULL;
}

int lenA = getListLength(headA);
int lenB = getListLength(headB);

if (lenA < lenB) {
for (int i = 0; i < lenB - lenA; ++i) {
headB = headB->next;
}
} else {
for (int i = 0; i < lenA - lenB; ++i) {
headA = headA->next;
}
}

while (headA != headB){
headA = headA->next;
headB = headB->next;
}
return headA;
}

int getListLength(ListNode *head){
int len=0;
while(head!=NULL){
head = head->next;
len++;
}
return len;
}
};

Review

本周阅读英文文章:The Problem With GDPR Is …

Technique

《HTTPS权威指南》关于OpenSSL的一些用法:
1、测试支持的协议,默认情况下s_client会尝试使用最高级的协议和远程服务器进行通信,并且在输出内容里面报告协商的版本信息。

1
2
3
4
5
6
7
8
9
10
11
$ openssl s_client -connect www.example.com:443 -tls1_2

New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256

2、测试会话复用,当加上-reconnect开关的时候,s_client命令可以用来测试会话复用。在此模式下,s_client与目标服务器连接6次,在第一次的时候会创建新的会话,然后在接下来的5次请求中复用同样的会话。

1
$ echo | openssl s_client -connect www.feistyduck.com:443 -reconnect

简化输出:

1
2
3
4
5
6
7
8
$ echo | openssl s_client -connect www.feistyduck.com:443 -reconnect -no_ssl2 2>/dev/null | grep 'New\|Reuse'

New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256

Share

本周在看刘超老师《第16讲 | 流媒体协议》时学习到的知识:
1、视频和图片的压缩过程有什么特点?
1)空间冗余:图像的相邻像素之间有较强的相关的性,一张图片相邻像素往往是渐变的,不是突变的,没必要每个像素都完整地的保存,可以隔几个保存一个,中间的用算法计算出来。
2)时间冗余:视频序列的相邻图像之间内容相似。一个视频中连续的图片也不是突变的,可以根据已有的图片进行预测和推断。
3)视觉冗余:人的视觉系统对某些细节不敏感,因此不会每一个细节都注意到,可以允许丢失一些数据。
4)编程冗余:不同像素值出现的概率不同,概率高的用的字节少,概率低的用的字节多,类似霍夫曼编码的思路。

2、视频序列分为三种帧:

  • I帧,也称关键帧。里面是完整的图片,只需要本帧数据,就可以完成解码。
  • P帧,前向预测编码帧。P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面,叠加上和本帧定义的差别,生成最终画面。
  • B帧,双向预测内插编码帧。B帧记录的是本帧与前后帧的差别。要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的数据与本帧数据的叠加,取得最终的画面。

3、一个视频,可以拆分成一系列的帧,每一帧拆分成一系列的片,每一片都放在一个NALU(Network Abstraction Layer Unit,网络提取层单元)里面,NALU之间都是通过特殊的起始标识符分隔,在每一个I帧的第一片前面,要插入单独保存SPS(序列参数集)和PPS(图像参数集)的NALU,最终形成一个长长的NALU序列。