auto commit

This commit is contained in:
CyC2018 2018-09-07 12:54:04 +08:00
parent 6ea965a9ef
commit f6e6808afe
15 changed files with 248 additions and 98 deletions

View File

@ -25,7 +25,6 @@
* [实体首部字段](#实体首部字段) * [实体首部字段](#实体首部字段)
* [五、具体应用](#五具体应用) * [五、具体应用](#五具体应用)
* [Cookie](#cookie) * [Cookie](#cookie)
* [6. Secure](#6-secure)
* [缓存](#缓存) * [缓存](#缓存)
* [连接管理](#连接管理) * [连接管理](#连接管理)
* [内容协商](#内容协商) * [内容协商](#内容协商)
@ -40,7 +39,6 @@
* [认证](#认证) * [认证](#认证)
* [完整性保护](#完整性保护) * [完整性保护](#完整性保护)
* [HTTPs 的缺点](#https-的缺点) * [HTTPs 的缺点](#https-的缺点)
* [配置 HTTPs](#配置-https)
* [七、HTTP/2.0](#七http20) * [七、HTTP/2.0](#七http20)
* [HTTP/1.x 缺陷](#http1x-缺陷) * [HTTP/1.x 缺陷](#http1x-缺陷)
* [二进制分帧层](#二进制分帧层) * [二进制分帧层](#二进制分帧层)
@ -377,11 +375,11 @@ console.log(document.cookie);
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
``` ```
## 6. Secure ### 7. Secure
标记为 Secure 的 Cookie 只能通过被 HTTPS 协议加密过的请求发送给服务端。但即便设置了 Secure 标记,敏感信息也不应该通过 Cookie 传输,因为 Cookie 有其固有的不安全性Secure 标记也无法提供确实的安全保障。 标记为 Secure 的 Cookie 只能通过被 HTTPS 协议加密过的请求发送给服务端。但即便设置了 Secure 标记,敏感信息也不应该通过 Cookie 传输,因为 Cookie 有其固有的不安全性Secure 标记也无法提供确实的安全保障。
### 7. Session ### 8. Session
除了可以将用户信息通过 Cookie 存储在用户浏览器中,也可以利用 Session 存储在服务器端,存储在服务器端的信息更加安全。 除了可以将用户信息通过 Cookie 存储在用户浏览器中,也可以利用 Session 存储在服务器端,存储在服务器端的信息更加安全。
@ -396,11 +394,11 @@ Session 可以存储在服务器上的文件、数据库或者内存中。也可
应该注意 Session ID 的安全性问题,不能让它被恶意攻击者轻易获取,那么就不能产生一个容易被猜到的 Session ID 值。此外,还需要经常重新生成 Session ID。在对安全性要求极高的场景下例如转账等操作除了使用 Session 管理用户状态之外,还需要对用户进行重新验证,比如重新输入密码,或者使用短信验证码等方式。 应该注意 Session ID 的安全性问题,不能让它被恶意攻击者轻易获取,那么就不能产生一个容易被猜到的 Session ID 值。此外,还需要经常重新生成 Session ID。在对安全性要求极高的场景下例如转账等操作除了使用 Session 管理用户状态之外,还需要对用户进行重新验证,比如重新输入密码,或者使用短信验证码等方式。
### 8. 浏览器禁用 Cookie ### 9. 浏览器禁用 Cookie
此时无法使用 Cookie 来保存用户信息,只能使用 Session。除此之外不能再将 Session ID 存放到 Cookie 中,而是使用 URL 重写技术,将 Session ID 作为 URL 的参数进行传递。 此时无法使用 Cookie 来保存用户信息,只能使用 Session。除此之外不能再将 Session ID 存放到 Cookie 中,而是使用 URL 重写技术,将 Session ID 作为 URL 的参数进行传递。
### 9. Cookie 与 Session 选择 ### 10. Cookie 与 Session 选择
- Cookie 只能存储 ASCII 码字符串,而 Session 则可以存取任何类型的数据,因此在考虑数据复杂性时首选 Session - Cookie 只能存储 ASCII 码字符串,而 Session 则可以存取任何类型的数据,因此在考虑数据复杂性时首选 Session
- Cookie 存储在浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 Cookie 中,可以将 Cookie 值进行加密,然后在服务器进行解密; - Cookie 存储在浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 Cookie 中,可以将 Cookie 值进行加密,然后在服务器进行解密;
@ -720,11 +718,6 @@ HTTPs 的报文摘要功能之所以安全,是因为它结合了加密和认
- 因为需要进行加密解密等过程,因此速度会更慢; - 因为需要进行加密解密等过程,因此速度会更慢;
- 需要支付证书授权的高额费用。 - 需要支付证书授权的高额费用。
## 配置 HTTPs
[Nginx 配置 HTTPS 服务器](https://aotu.io/notes/2016/08/16/nginx-https/index.html)
# 七、HTTP/2.0 # 七、HTTP/2.0
## HTTP/1.x 缺陷 ## HTTP/1.x 缺陷
@ -849,7 +842,7 @@ DELETE /idX/delete HTTP/1.1 -> Returns 404
# 九、HTTP/1.0 与 HTTP/1.1 的区别 # 九、HTTP/1.0 与 HTTP/1.1 的区别
> 详细内容请见上文 详细内容请见上文
- HTTP/1.1 默认是长连接 - HTTP/1.1 默认是长连接

View File

@ -182,8 +182,10 @@ public static void readFileContent(String filePath) throws IOException {
```java ```java
public static void main(String[] args) throws IOException, ClassNotFoundException { public static void main(String[] args) throws IOException, ClassNotFoundException {
A a1 = new A(123, "abc"); A a1 = new A(123, "abc");
String objectFile = "file/a1"; String objectFile = "file/a1";
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(objectFile)); ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(objectFile));
objectOutputStream.writeObject(a1); objectOutputStream.writeObject(a1);
objectOutputStream.close(); objectOutputStream.close();
@ -195,6 +197,7 @@ public static void main(String[] args) throws IOException, ClassNotFoundExceptio
} }
private static class A implements Serializable { private static class A implements Serializable {
private int x; private int x;
private String y; private String y;

View File

@ -685,26 +685,26 @@ protected void finalize() throws Throwable {}
**1. 等价关系** **1. 等价关系**
(一)自反性 自反性
```java ```java
x.equals(x); // true x.equals(x); // true
``` ```
(二)对称性 对称性
```java ```java
x.equals(y) == y.equals(x); // true x.equals(y) == y.equals(x); // true
``` ```
(三)传递性 传递性
```java ```java
if (x.equals(y) && y.equals(z)) if (x.equals(y) && y.equals(z))
x.equals(z); // true; x.equals(z); // true;
``` ```
(四)一致性 一致性
多次调用 equals() 方法结果不变 多次调用 equals() 方法结果不变
@ -712,7 +712,7 @@ if (x.equals(y) && y.equals(z))
x.equals(y) == x.equals(y); // true x.equals(y) == x.equals(y); // true
``` ```
(五)与 null 的比较 与 null 的比较
对任何不是 null 的对象 x 调用 x.equals(null) 结果都为 false 对任何不是 null 的对象 x 调用 x.equals(null) 结果都为 false
@ -741,6 +741,7 @@ System.out.println(x == y); // false
```java ```java
public class EqualExample { public class EqualExample {
private int x; private int x;
private int y; private int y;
private int z; private int z;

View File

@ -30,7 +30,7 @@
# 一、运行时数据区域 # 一、运行时数据区域
<div align="center"> <img src="../pics//c9ad2bf4-5580-4018-bce4-1b9a71804d9c.png" width="400"/> </div><br> <div align="center"> <img src="../pics//c9ad2bf4-5580-4018-bce4-1b9a71804d9c.png" width="450"/> </div><br>
## 程序计数器 ## 程序计数器
@ -40,7 +40,7 @@
每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。 每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。
<div align="center"> <img src="../pics//926c7438-c5e1-4b94-840a-dcb24ff1dafe.png" width="450"/> </div><br> <div align="center"> <img src="../pics//926c7438-c5e1-4b94-840a-dcb24ff1dafe.png" width="500"/> </div><br>
可以通过 -Xss 这个虚拟机参数来指定每个线程的 Java 虚拟机栈内存大小: 可以通过 -Xss 这个虚拟机参数来指定每个线程的 Java 虚拟机栈内存大小:

View File

@ -316,7 +316,7 @@ FLOAT、DOUBLE 和 DECIMAL 都可以指定列宽,例如 DECIMAL(18, 9) 表示
VARCHAR 这种变长类型能够节省空间,因为只需要存储必要的内容。但是在执行 UPDATE 时可能会使行变得比原来长当超出一个页所能容纳的大小时就要执行额外的操作。MyISAM 会将行拆成不同的片段存储,而 InnoDB 则需要分裂页来使行放进页内。 VARCHAR 这种变长类型能够节省空间,因为只需要存储必要的内容。但是在执行 UPDATE 时可能会使行变得比原来长当超出一个页所能容纳的大小时就要执行额外的操作。MyISAM 会将行拆成不同的片段存储,而 InnoDB 则需要分裂页来使行放进页内。
VARCHAR 会保留字符串末尾的空格,而 CHAR 会删除 在进行存储和检索时,会保留 VARCHAR 末尾的空格,而会删除 CHAR 末尾的空格
## 时间和日期 ## 时间和日期

View File

@ -307,14 +307,14 @@ select 可移植性更好,几乎被所有主流平台所支持。
poll 没有最大描述符数量的限制,如果平台支持并且对实时性要求不高,应该使用 poll 而不是 select。 poll 没有最大描述符数量的限制,如果平台支持并且对实时性要求不高,应该使用 poll 而不是 select。
需要同时监控小于 1000 个描述符,就没有必要使用 epoll因为这个应用场景下并不能体现 epoll 的优势。
需要监控的描述符状态变化多,而且都是非常短暂的,也没有必要使用 epoll。因为 epoll 中的所有描述符都存储在内核中,造成每次需要对描述符的状态改变都需要通过 epoll_ctl() 进行系统调用频繁系统调用降低效率。并且epoll 的描述符存储在内核,不容易调试。
### 3. epoll 应用场景 ### 3. epoll 应用场景
只需要运行在 Linux 平台上,并且有非常大量的描述符需要同时轮询,而且这些连接最好是长连接。 只需要运行在 Linux 平台上,并且有非常大量的描述符需要同时轮询,而且这些连接最好是长连接。
需要同时监控小于 1000 个描述符,就没有必要使用 epoll因为这个应用场景下并不能体现 epoll 的优势。
需要监控的描述符状态变化多,而且都是非常短暂的,也没有必要使用 epoll。因为 epoll 中的所有描述符都存储在内核中,造成每次需要对描述符的状态改变都需要通过 epoll_ctl() 进行系统调用频繁系统调用降低效率。并且epoll 的描述符存储在内核,不容易调试。
# 参考资料 # 参考资料
- Stevens W R, Fenner B, Rudoff A M. UNIX network programming[M]. Addison-Wesley Professional, 2004. - Stevens W R, Fenner B, Rudoff A M. UNIX network programming[M]. Addison-Wesley Professional, 2004.

View File

@ -167,7 +167,7 @@ Zookeeper 提供了一种树形结构级的命名空间,/app1/p_1 节点的父
可用性指分布式系统在面对各种异常时可以提供正常服务的能力可以用系统可用时间占总时间的比值来衡量4 个 9 的可用性表示系统 99.99% 的时间是可用的。 可用性指分布式系统在面对各种异常时可以提供正常服务的能力可以用系统可用时间占总时间的比值来衡量4 个 9 的可用性表示系统 99.99% 的时间是可用的。
在可用性条件下,要求系统提供的服务一直处于可用的状态,对于用户的每一个操请求总是能够在有限的时间内返回结果。 在可用性条件下,要求系统提供的服务一直处于可用的状态,对于用户的每一个操请求总是能够在有限的时间内返回结果。
## 分区容忍性 ## 分区容忍性

View File

@ -1433,7 +1433,8 @@ public boolean IsPopOrder(int[] pushSequence, int[] popSequence) {
Stack<Integer> stack = new Stack<>(); Stack<Integer> stack = new Stack<>();
for (int pushIndex = 0, popIndex = 0; pushIndex < n; pushIndex++) { for (int pushIndex = 0, popIndex = 0; pushIndex < n; pushIndex++) {
stack.push(pushSequence[pushIndex]); stack.push(pushSequence[pushIndex]);
while (popIndex < n && stack.peek() == popSequence[popIndex]) { while (popIndex < n && !stack.isEmpty()
&& stack.peek() == popSequence[popIndex]) {
stack.pop(); stack.pop();
popIndex++; popIndex++;
} }
@ -1578,7 +1579,7 @@ private boolean verify(int[] sequence, int first, int last) {
int cutIndex = first; int cutIndex = first;
while (cutIndex < last && sequence[cutIndex] <= rootVal) while (cutIndex < last && sequence[cutIndex] <= rootVal)
cutIndex++; cutIndex++;
for (int i = cutIndex + 1; i < last; i++) for (int i = cutIndex; i < last; i++)
if (sequence[i] < rootVal) if (sequence[i] < rootVal)
return false; return false;
return verify(sequence, first, cutIndex - 1) && verify(sequence, cutIndex, last - 1); return verify(sequence, first, cutIndex - 1) && verify(sequence, cutIndex, last - 1);

View File

@ -13,6 +13,8 @@
跨站脚本攻击Cross-Site Scripting, XSS可以将代码注入到用户浏览的网页上这种代码包括 HTML 和 JavaScript。 跨站脚本攻击Cross-Site Scripting, XSS可以将代码注入到用户浏览的网页上这种代码包括 HTML 和 JavaScript。
## 攻击原理
例如有一个论坛网站,攻击者可以在上面发布以下内容: 例如有一个论坛网站,攻击者可以在上面发布以下内容:
```html ```html
@ -43,40 +45,23 @@
例如将 `<` 转义为 `&lt;`,将 `>` 转义为 `&gt;`,从而避免 HTML 和 Jascript 代码的运行。 例如将 `<` 转义为 `&lt;`,将 `>` 转义为 `&gt;`,从而避免 HTML 和 Jascript 代码的运行。
## 富文本编辑器
富文本编辑器允许用户输入 HTML 代码,就不能简单地将 `<` 等字符进行过滤了,极大地提高了 XSS 攻击的可能性。 富文本编辑器允许用户输入 HTML 代码,就不能简单地将 `<` 等字符进行过滤了,极大地提高了 XSS 攻击的可能性。
富文本编辑器通常采用 XSS filter 来防范 XSS 攻击,通过定义一些标签白名单或者黑名单,从而不允许有攻击性的 HTML 代码的输入。 富文本编辑器通常采用 XSS filter 来防范 XSS 攻击,通过定义一些标签白名单或者黑名单,从而不允许有攻击性的 HTML 代码的输入。
以下例子中form 和 script 等标签都被转义,而 h 和 p 等标签将会保留。 以下例子中form 和 script 等标签都被转义,而 h 和 p 等标签将会保留。
> [XSS 过滤在线测试](http://jsxss.com/zh/try.html)
```html ```html
<h1 id="title">XSS Demo</h1> <h1 id="title">XSS Demo</h1>
<p class="text-center"> <p>123</p>
Sanitize untrusted HTML (to prevent XSS) with a configuration specified by a Whitelist.
</p>
<form> <form>
<input type="text" name="q" value="test"> <input type="text" name="q" value="test">
<button id="submit">Submit</button>
</form> </form>
<pre>hello</pre> <pre>hello</pre>
<p>
<a href="http://jsxss.com">http</a>
</p>
<h3>Features:</h3>
<ul>
<li>Specifies HTML tags and their attributes allowed with whitelist</li>
<li>Handle any tags or attributes using custom function</li>
</ul>
<script type="text/javascript"> <script type="text/javascript">
alert(/xss/); alert(/xss/);
</script> </script>
@ -85,32 +70,21 @@ alert(/xss/);
```html ```html
<h1>XSS Demo</h1> <h1>XSS Demo</h1>
<p> <p>123</p>
Sanitize untrusted HTML (to prevent XSS) with a configuration specified by a Whitelist.
</p>
&lt;form&gt; &lt;form&gt;
&lt;input type="text" name="q" value="test"&gt; &lt;input type="text" name="q" value="test"&gt;
&lt;button id="submit"&gt;Submit&lt;/button&gt;
&lt;/form&gt; &lt;/form&gt;
<pre>hello</pre> <pre>hello</pre>
<p>
<a href="http://jsxss.com">http</a>
</p>
<h3>Features:</h3>
<ul>
<li>Specifies HTML tags and their attributes allowed with whitelist</li>
<li>Handle any tags or attributes using custom function</li>
</ul>
&lt;script type="text/javascript"&gt; &lt;script type="text/javascript"&gt;
alert(/xss/); alert(/xss/);
&lt;/script&gt; &lt;/script&gt;
``` ```
> [XSS 过滤在线测试](http://jsxss.com/zh/try.html)
# 二、跨站请求伪造 # 二、跨站请求伪造
## 概念 ## 概念
@ -119,6 +93,8 @@ alert(/xss/);
XSS 利用的是用户对指定网站的信任CSRF 利用的是网站对用户浏览器的信任。 XSS 利用的是用户对指定网站的信任CSRF 利用的是网站对用户浏览器的信任。
## 攻击原理
假如一家银行用以执行转账操作的 URL 地址如下: 假如一家银行用以执行转账操作的 URL 地址如下:
``` ```

View File

@ -70,7 +70,7 @@
接收端能够从消息队列成功消费一次消息。 接收端能够从消息队列成功消费一次消息。
实现方法: 两种实现方法:
- 保证接收端处理消息的业务逻辑具有幂等性:只要具有幂等性,那么消费多少次消息,最后处理的结果都是一样的。 - 保证接收端处理消息的业务逻辑具有幂等性:只要具有幂等性,那么消费多少次消息,最后处理的结果都是一样的。
- 保证消息具有唯一编号,并使用一张日志表来记录已经消费的消息编号。 - 保证消息具有唯一编号,并使用一张日志表来记录已经消费的消息编号。

View File

@ -58,6 +58,7 @@ public class LRU<K, V> implements Iterable<K> {
} }
} }
public LRU(int maxSize) { public LRU(int maxSize) {
this.maxSize = maxSize; this.maxSize = maxSize;
@ -70,6 +71,7 @@ public class LRU<K, V> implements Iterable<K> {
tail.pre = head; tail.pre = head;
} }
public V get(K key) { public V get(K key) {
if (!map.containsKey(key)) { if (!map.containsKey(key)) {
@ -83,6 +85,7 @@ public class LRU<K, V> implements Iterable<K> {
return node.v; return node.v;
} }
public void put(K key, V value) { public void put(K key, V value) {
if (map.containsKey(key)) { if (map.containsKey(key)) {
@ -100,30 +103,34 @@ public class LRU<K, V> implements Iterable<K> {
} }
} }
private void unlink(Node node) { private void unlink(Node node) {
Node pre = node.pre; Node pre = node.pre;
node.pre = node.next; Node next = node.next;
node.next = pre; pre.next = next;
next.pre = pre;
} }
private void appendHead(Node node) { private void appendHead(Node node) {
node.next = head.next; node.next = head.next;
node.pre = head;
head.next = node; head.next = node;
} }
private Node removeTail() { private Node removeTail() {
Node node = tail.pre; Node node = tail.pre;
node.pre = tail; tail.pre = node.pre;
return node; return node;
} }
@Override @Override
public Iterator<K> iterator() { public Iterator<K> iterator() {
return new Iterator<K>() { return new Iterator<K>() {
private Node cur = head.next; private Node cur = head.next;
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return cur != tail; return cur != tail;
@ -162,7 +169,7 @@ public class LRU<K, V> implements Iterable<K> {
使用 Redis、Memcache 等分布式缓存将数据缓存在分布式缓存系统中。 使用 Redis、Memcache 等分布式缓存将数据缓存在分布式缓存系统中。
相对于本地缓存来说,分布式缓存单独部署,可以根据需求分配硬件资源。不仅如此,服务器集群都可以访问分布式缓存,而本地缓存需要在服务器集群之间进行同步,实现和性能开销上都非常大。 相对于本地缓存来说,分布式缓存单独部署,可以根据需求分配硬件资源。不仅如此,服务器集群都可以访问分布式缓存,而本地缓存需要在服务器集群之间进行同步,实现难度和性能开销上都非常大。
## 数据库缓存 ## 数据库缓存
@ -241,7 +248,7 @@ Distributed Hash TableDHT 是一种哈希分布方式,其目的是为了
<div align="center"> <img src="../pics//68b110b9-76c6-4ee2-b541-4145e65adb3e.jpg"/> </div><br> <div align="center"> <img src="../pics//68b110b9-76c6-4ee2-b541-4145e65adb3e.jpg"/> </div><br>
一致性哈希在增加或者删除节点时只会影响到哈希环中相邻的节点,例如下图中新增节点 X只需要将它一个节点 C 上的数据重新进行分布即可,对于节点 A、B、D 都没有影响。 一致性哈希在增加或者删除节点时只会影响到哈希环中相邻的节点,例如下图中新增节点 X只需要将它一个节点 C 上的数据重新进行分布即可,对于节点 A、B、D 都没有影响。
<div align="center"> <img src="../pics//66402828-fb2b-418f-83f6-82153491bcfe.jpg"/> </div><br> <div align="center"> <img src="../pics//66402828-fb2b-418f-83f6-82153491bcfe.jpg"/> </div><br>

View File

@ -13,8 +13,8 @@
* [经典同步问题](#经典同步问题) * [经典同步问题](#经典同步问题)
* [进程通信](#进程通信) * [进程通信](#进程通信)
* [三、死锁](#三死锁) * [三、死锁](#三死锁)
* [死锁的必要条件](#死锁的必要条件) * [必要条件](#必要条件)
* [死锁的处理方法](#死锁的处理方法) * [处理方法](#处理方法)
* [鸵鸟策略](#鸵鸟策略) * [鸵鸟策略](#鸵鸟策略)
* [死锁检测与死锁恢复](#死锁检测与死锁恢复) * [死锁检测与死锁恢复](#死锁检测与死锁恢复)
* [死锁预防](#死锁预防) * [死锁预防](#死锁预防)
@ -181,7 +181,7 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 H
Ⅳ 通信方面 Ⅳ 通信方面
进程间通信 (IPC) 需要进程同步和互斥手段的辅助,以保证数据的一致性。而线程间可以通过直接读/写同一进程中的数据段(如全局变量)来进行通信。 进程间通信需要进程同步和互斥手段的辅助,以保证数据的一致性。而线程间可以通过直接读/写同一进程中的数据段(如全局变量)来进行通信(需要做好同步)
## 进程状态的切换 ## 进程状态的切换
@ -458,6 +458,116 @@ void writer() {
} }
``` ```
以下内容由 [@Bandi Yugandhar](https://github.com/yugandharbandi) 提供。
The first case may result Writer to starve. This case favous Writers i.e no writer, once added to the queue, shall be kept waiting longer than absolutely necessary(only when there are readers that entered the queue before the writer).
```source-c
int readcount, writecount; //(initial value = 0)
semaphore rmutex, wmutex, readLock, resource; //(initial value = 1)
//READER
void reader() {
<ENTRY Section>
down(&readLock); // reader is trying to enter
down(&rmutex); // lock to increase readcount
readcount++;
if (readcount == 1)
down(&resource); //if you are the first reader then lock the resource
up(&rmutex); //release for other readers
up(&readLock); //Done with trying to access the resource
<CRITICAL Section>
//reading is performed
<EXIT Section>
down(&rmutex); //reserve exit section - avoids race condition with readers
readcount--; //indicate you're leaving
if (readcount == 0) //checks if you are last reader leaving
up(&resource); //if last, you must release the locked resource
up(&rmutex); //release exit section for other readers
}
//WRITER
void writer() {
<ENTRY Section>
down(&wmutex); //reserve entry section for writers - avoids race conditions
writecount++; //report yourself as a writer entering
if (writecount == 1) //checks if you're first writer
down(&readLock); //if you're first, then you must lock the readers out. Prevent them from trying to enter CS
up(&wmutex); //release entry section
<CRITICAL Section>
down(&resource); //reserve the resource for yourself - prevents other writers from simultaneously editing the shared resource
//writing is performed
up(&resource); //release file
<EXIT Section>
down(&wmutex); //reserve exit section
writecount--; //indicate you're leaving
if (writecount == 0) //checks if you're the last writer
up(&readLock); //if you're last writer, you must unlock the readers. Allows them to try enter CS for reading
up(&wmutex); //release exit section
}
```
We can observe that every reader is forced to acquire ReadLock. On the otherhand, writers doesnt need to lock individually. Once the first writer locks the ReadLock, it will be released only when there is no writer left in the queue.
From the both cases we observed that either reader or writer has to starve. Below solutionadds the constraint that no thread shall be allowed to starve; that is, the operation of obtaining a lock on the shared data will always terminate in a bounded amount of time.
```source-c
int readCount; // init to 0; number of readers currently accessing resource
// all semaphores initialised to 1
Semaphore resourceAccess; // controls access (read/write) to the resource
Semaphore readCountAccess; // for syncing changes to shared variable readCount
Semaphore serviceQueue; // FAIRNESS: preserves ordering of requests (signaling must be FIFO)
void writer()
{
down(&serviceQueue); // wait in line to be servicexs
// <ENTER>
down(&resourceAccess); // request exclusive access to resource
// </ENTER>
up(&serviceQueue); // let next in line be serviced
// <WRITE>
writeResource(); // writing is performed
// </WRITE>
// <EXIT>
up(&resourceAccess); // release resource access for next reader/writer
// </EXIT>
}
void reader()
{
down(&serviceQueue); // wait in line to be serviced
down(&readCountAccess); // request exclusive access to readCount
// <ENTER>
if (readCount == 0) // if there are no readers already reading:
down(&resourceAccess); // request resource access for readers (writers blocked)
readCount++; // update count of active readers
// </ENTER>
up(&serviceQueue); // let next in line be serviced
up(&readCountAccess); // release access to readCount
// <READ>
readResource(); // reading is performed
// </READ>
down(&readCountAccess); // request exclusive access to readCount
// <EXIT>
readCount--; // update count of active readers
if (readCount == 0) // if there are no readers left:
up(&resourceAccess); // release resource access for all
// </EXIT>
up(&readCountAccess); // release access to readCount
}
```
### 2. 哲学家进餐问题 ### 2. 哲学家进餐问题
<div align="center"> <img src="../pics//a9077f06-7584-4f2b-8c20-3a8e46928820.jpg"/> </div><br> <div align="center"> <img src="../pics//a9077f06-7584-4f2b-8c20-3a8e46928820.jpg"/> </div><br>
@ -596,7 +706,7 @@ FIFO 常用于客户-服务器应用程序中FIFO 用作汇聚点,在客户
# 三、死锁 # 三、死锁
## 死锁的必要条件 ## 必要条件
<div align="center"> <img src="../pics//c037c901-7eae-4e31-a1e4-9d41329e5c3e.png"/> </div><br> <div align="center"> <img src="../pics//c037c901-7eae-4e31-a1e4-9d41329e5c3e.png"/> </div><br>
@ -605,7 +715,7 @@ FIFO 常用于客户-服务器应用程序中FIFO 用作汇聚点,在客户
- 不可抢占:已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。 - 不可抢占:已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。
- 环路等待:有两个或者两个以上的进程组成一条环路,该环路中的每个进程都在等待下一个进程所占有的资源。 - 环路等待:有两个或者两个以上的进程组成一条环路,该环路中的每个进程都在等待下一个进程所占有的资源。
## 死锁的处理方法 ## 处理方法
主要有以下四种方法: 主要有以下四种方法:

View File

@ -5,7 +5,7 @@
* [主机之间的通信方式](#主机之间的通信方式) * [主机之间的通信方式](#主机之间的通信方式)
* [电路交换与分组交换](#电路交换与分组交换) * [电路交换与分组交换](#电路交换与分组交换)
* [时延](#时延) * [时延](#时延)
* [计算机网络体系结构*](#计算机网络体系结构) * [计算机网络体系结构](#计算机网络体系结构)
* [二、物理层](#二物理层) * [二、物理层](#二物理层)
* [通信方式](#通信方式) * [通信方式](#通信方式)
* [带通调制](#带通调制) * [带通调制](#带通调制)
@ -13,14 +13,14 @@
* [基本问题](#基本问题) * [基本问题](#基本问题)
* [信道分类](#信道分类) * [信道分类](#信道分类)
* [信道复用技术](#信道复用技术) * [信道复用技术](#信道复用技术)
* [CSMA/CD 协议*](#csmacd-协议) * [CSMA/CD 协议](#csmacd-协议)
* [PPP 协议](#ppp-协议) * [PPP 协议](#ppp-协议)
* [MAC 地址](#mac-地址) * [MAC 地址](#mac-地址)
* [局域网](#局域网) * [局域网](#局域网)
* [以太网*](#以太网) * [以太网](#以太网)
* [交换机*](#交换机) * [交换机](#交换机)
* [虚拟局域网](#虚拟局域网) * [虚拟局域网](#虚拟局域网)
* [四、网络层*](#四网络层) * [四、网络层](#四网络层)
* [概述](#概述) * [概述](#概述)
* [IP 数据报格式](#ip-数据报格式) * [IP 数据报格式](#ip-数据报格式)
* [IP 地址编址方式](#ip-地址编址方式) * [IP 地址编址方式](#ip-地址编址方式)
@ -31,7 +31,7 @@
* [路由器的结构](#路由器的结构) * [路由器的结构](#路由器的结构)
* [路由器分组转发流程](#路由器分组转发流程) * [路由器分组转发流程](#路由器分组转发流程)
* [路由选择协议](#路由选择协议) * [路由选择协议](#路由选择协议)
* [五、运输层*](#五运输层) * [五、运输层](#五运输层)
* [UDP 和 TCP 的特点](#udp-和-tcp-的特点) * [UDP 和 TCP 的特点](#udp-和-tcp-的特点)
* [UDP 首部格式](#udp-首部格式) * [UDP 首部格式](#udp-首部格式)
* [TCP 首部格式](#tcp-首部格式) * [TCP 首部格式](#tcp-首部格式)
@ -121,7 +121,7 @@
分组在路由器的输入队列和输出队列中排队等待的时间,取决于网络当前的通信量。 分组在路由器的输入队列和输出队列中排队等待的时间,取决于网络当前的通信量。
## 计算机网络体系结构* ## 计算机网络体系结构
<div align="center"> <img src="../pics//426df589-6f97-4622-b74d-4a81fcb1da8e.png" width="600"/> </div><br> <div align="center"> <img src="../pics//426df589-6f97-4622-b74d-4a81fcb1da8e.png" width="600"/> </div><br>
@ -129,11 +129,11 @@
- **应用层** :为特定应用程序提供数据传输服务,例如 HTTP、DNS 等。数据单位为报文。 - **应用层** :为特定应用程序提供数据传输服务,例如 HTTP、DNS 等。数据单位为报文。
- **运输层** :提供的是进程间的通用数据传输服务。由于应用层协议很多,定义通用的运输层协议就可以支持不断增多的应用层协议。运输层包括两种协议:传输控制协议 TCP提供面向连接、可靠的数据传输服务数据单位为报文段用户数据报协议 UDP提供无连接、尽最大努力的数据传输服务数据单位为用户数据报。TCP 主要提供完整性服务UDP 主要提供及时性服务。 - **运输层** 为进程提供通用数据传输服务。由于应用层协议很多,定义通用的运输层协议就可以支持不断增多的应用层协议。运输层包括两种协议:传输控制协议 TCP提供面向连接、可靠的数据传输服务数据单位为报文段用户数据报协议 UDP提供无连接、尽最大努力的数据传输服务数据单位为用户数据报。TCP 主要提供完整性服务UDP 主要提供及时性服务。
- **网络层** :为主机间提供数据传输服务,而运输层协议是为主机中的进程提供服务。网络层把运输层传递下来的报文段或者用户数据报封装成分组。 - **网络层** :为主机提供数据传输服务。而运输层协议是为主机中的进程提供数据传输服务。网络层把运输层传递下来的报文段或者用户数据报封装成分组。
- **数据链路层** :网络层针对的还是主机之间的数据传输服务,而主机之间可以有很多链路,链路层协议就是为同一链路的主机提供服务。数据链路层把网络层传下来的分组封装成帧。 - **数据链路层** :网络层针对的还是主机之间的数据传输服务,而主机之间可以有很多链路,链路层协议就是为同一链路的主机提供数据传输服务。数据链路层把网络层传下来的分组封装成帧。
- **物理层** :考虑的是怎样在传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。 - **物理层** :考虑的是怎样在传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。
@ -271,7 +271,7 @@ TCP/IP 协议族是一种沙漏形状中间小两边大IP 协议在其中
<div align="center"> <img src="../pics//92ad9bae-7d02-43ba-8115-a9d6f530ca28.png" width="600"/> </div><br> <div align="center"> <img src="../pics//92ad9bae-7d02-43ba-8115-a9d6f530ca28.png" width="600"/> </div><br>
## CSMA/CD 协议* ## CSMA/CD 协议
CSMA/CD 表示载波监听多点接入 / 碰撞检测。 CSMA/CD 表示载波监听多点接入 / 碰撞检测。
@ -316,7 +316,7 @@ MAC 地址是链路层地址,长度为 6 字节48 位),用于唯一标
<div align="center"> <img src="../pics//a6026bb4-3daf-439f-b1ec-a5a24e19d2fb.jpg" width="600"/> </div><br> <div align="center"> <img src="../pics//a6026bb4-3daf-439f-b1ec-a5a24e19d2fb.jpg" width="600"/> </div><br>
## 以太网* ## 以太网
以太网是一种星型拓扑结构局域网。 以太网是一种星型拓扑结构局域网。
@ -333,7 +333,7 @@ MAC 地址是链路层地址,长度为 6 字节48 位),用于唯一标
<div align="center"> <img src="../pics//50d38e84-238f-4081-8876-14ef6d7938b5.jpg" width="600"/> </div><br> <div align="center"> <img src="../pics//50d38e84-238f-4081-8876-14ef6d7938b5.jpg" width="600"/> </div><br>
## 交换机* ## 交换机
交换机具有自学习能力,学习的是交换表的内容,交换表中存储着 MAC 地址到接口的映射。 交换机具有自学习能力,学习的是交换表的内容,交换表中存储着 MAC 地址到接口的映射。
@ -353,7 +353,7 @@ MAC 地址是链路层地址,长度为 6 字节48 位),用于唯一标
<div align="center"> <img src="../pics//a74b70ac-323a-4b31-b4d5-90569b8a944b.png" width="500"/> </div><br> <div align="center"> <img src="../pics//a74b70ac-323a-4b31-b4d5-90569b8a944b.png" width="500"/> </div><br>
# 四、网络层* # 四、网络层
## 概述 ## 概述
@ -578,7 +578,7 @@ BGP 只能寻找一条比较好的路由,而不是最佳路由。
<div align="center"> <img src="../pics//9cd0ae20-4fb5-4017-a000-f7d3a0eb3529.png" width="600"/> </div><br> <div align="center"> <img src="../pics//9cd0ae20-4fb5-4017-a000-f7d3a0eb3529.png" width="600"/> </div><br>
# 五、运输层* # 五、运输层
网络层只把分组发送到目的主机,但是真正通信的并不是主机而是主机中的进程。运输层提供了进程间的逻辑通信,运输层向高层用户屏蔽了下面网络层的核心细节,使应用程序看起来像是在两个运输层实体之间有一条端到端的逻辑通信信道。 网络层只把分组发送到目的主机,但是真正通信的并不是主机而是主机中的进程。运输层提供了进程间的逻辑通信,运输层向高层用户屏蔽了下面网络层的核心细节,使应用程序看起来像是在两个运输层实体之间有一条端到端的逻辑通信信道。

View File

@ -175,6 +175,50 @@ public class Singleton {
} }
``` ```
#### Ⅵ 枚举实现
```java
public enum Singleton {
INSTANCE;
private String objName;
public String getObjName() {
return objName;
}
public void setObjName(String objName) {
this.objName = objName;
}
public static void main(String[] args) {
// 单例测试
Singleton firstSingleton = Singleton.INSTANCE;
firstSingleton.setObjName("firstName");
System.out.println(firstSingleton.getObjName());
Singleton secondSingleton = Singleton.INSTANCE;
secondSingleton.setObjName("secondName");
System.out.println(firstSingleton.getObjName());
System.out.println(secondSingleton.getObjName());
// 反射获取实例测试
try {
Singleton[] enumConstants = Singleton.class.getEnumConstants();
for (Singleton enumConstant : enumConstants) {
System.out.println(enumConstant.getObjName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
该实现在多次序列化再进行反序列化之后,不会得到多个实例。而其它实现,为了保证不会出现反序列化之后出现多个实例,需要使用 transient 修饰所有字段,并且实现序列化和反序列化的方法。 该实现在多次序列化再进行反序列化之后,不会得到多个实例。而其它实现,为了保证不会出现反序列化之后出现多个实例,需要使用 transient 修饰所有字段,并且实现序列化和反序列化的方法。
该实现可以防止反射攻击。在其它实现中,通过 setAccessible() 方法可以将私有构造函数的访问级别设置为 public然后调用构造函数从而实例化对象如果要防止这种攻击需要在构造函数中添加防止实例化第二个对象的代码。但是该实现是由 JVM 保证只会实例化一次,因此不会出现上述的反射攻击。 该实现可以防止反射攻击。在其它实现中,通过 setAccessible() 方法可以将私有构造函数的访问级别设置为 public然后调用构造函数从而实例化对象如果要防止这种攻击需要在构造函数中添加防止实例化第二个对象的代码。但是该实现是由 JVM 保证只会实例化一次,因此不会出现上述的反射攻击。
@ -595,25 +639,30 @@ abc
```java ```java
public abstract class Handler { public abstract class Handler {
protected Handler successor; protected Handler successor;
public Handler(Handler successor) { public Handler(Handler successor) {
this.successor = successor; this.successor = successor;
} }
protected abstract void handleRequest(Request request); protected abstract void handleRequest(Request request);
} }
``` ```
```java ```java
public class ConcreteHandler1 extends Handler { public class ConcreteHandler1 extends Handler {
public ConcreteHandler1(Handler successor) { public ConcreteHandler1(Handler successor) {
super(successor); super(successor);
} }
@Override @Override
protected void handleRequest(Request request) { protected void handleRequest(Request request) {
if (request.getType() == RequestType.type1) { if (request.getType() == RequestType.TYPE1) {
System.out.println(request.getName() + " is handle by ConcreteHandler1"); System.out.println(request.getName() + " is handle by ConcreteHandler1");
return; return;
} }
@ -625,14 +674,16 @@ public class ConcreteHandler1 extends Handler {
``` ```
```java ```java
public class ConcreteHandler2 extends Handler{ public class ConcreteHandler2 extends Handler {
public ConcreteHandler2(Handler successor) { public ConcreteHandler2(Handler successor) {
super(successor); super(successor);
} }
@Override @Override
protected void handleRequest(Request request) { protected void handleRequest(Request request) {
if (request.getType() == RequestType.type2) { if (request.getType() == RequestType.TYPE2) {
System.out.println(request.getName() + " is handle by ConcreteHandler2"); System.out.println(request.getName() + " is handle by ConcreteHandler2");
return; return;
} }
@ -645,38 +696,47 @@ public class ConcreteHandler2 extends Handler{
```java ```java
public class Request { public class Request {
private RequestType type; private RequestType type;
private String name; private String name;
public Request(RequestType type, String name) { public Request(RequestType type, String name) {
this.type = type; this.type = type;
this.name = name; this.name = name;
} }
public RequestType getType() { public RequestType getType() {
return type; return type;
} }
public String getName() { public String getName() {
return name; return name;
} }
} }
``` ```
```java ```java
public enum RequestType { public enum RequestType {
type1, type2 TYPE1, TYPE2
} }
``` ```
```java ```java
public class Client { public class Client {
public static void main(String[] args) { public static void main(String[] args) {
Handler handler1 = new ConcreteHandler1(null); Handler handler1 = new ConcreteHandler1(null);
Handler handler2 = new ConcreteHandler2(handler1); Handler handler2 = new ConcreteHandler2(handler1);
Request request1 = new Request(RequestType.type1, "request1");
Request request1 = new Request(RequestType.TYPE1, "request1");
handler2.handleRequest(request1); handler2.handleRequest(request1);
Request request2 = new Request(RequestType.type2, "request2");
Request request2 = new Request(RequestType.TYPE2, "request2");
handler2.handleRequest(request2); handler2.handleRequest(request2);
} }
} }

View File

@ -18,12 +18,12 @@
负载均衡器可以用来实现高可用以及伸缩性: 负载均衡器可以用来实现高可用以及伸缩性:
- 高可用:当某个节点故障时,负载均衡器会将用户请求转发到另外的节点上,从而保证所有服务持续可用; - 高可用:当某个节点故障时,负载均衡器会将用户请求转发到另外的节点上,从而保证所有服务持续可用;
- 伸缩性:可以很容易地添加移除节点。 - 伸缩性:根据系统整体负载情况,可以很容易地添加移除节点。
负载均衡运行过程包含两个部分: 负载均衡运行过程包含两个部分:
1. 根据负载均衡算法得到请求转发的节点; 1. 根据负载均衡算法得到转发的节点;
2. 将请求进行转发。 2. 进行转发。
## 负载均衡算法 ## 负载均衡算法
@ -205,4 +205,3 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服
- [Session Management using Spring Session with JDBC DataStore](https://sivalabs.in/2018/02/session-management-using-spring-session-jdbc-datastore/) - [Session Management using Spring Session with JDBC DataStore](https://sivalabs.in/2018/02/session-management-using-spring-session-jdbc-datastore/)