HashTable
1 | /** |
处理哈希冲突
- 开放地址法(线性探测,平方探测)
- 链地址法
- 再哈希法
- 建立公共溢出区
凡事必先骑上虎背
1 | /** |
阻塞和非阻塞这两个概念与程序(线程)等待消息通知(无所谓同步或者异步)时的状态有关。也就是说阻塞与非阻塞主要是程序(线程)等待消息通知时的状态角度来说的。
阻塞
调用是指调用结果返回之前,当前线程会被挂起,一直处于等待消息通知,不能够执行其他业务。函数只有在得到结果之后才会返回。
对于同步调用来说,很多时候当前线程可能还是激活的,只是从逻辑上当前函数没有返回而已,此时,这个线程可能也会处理其他的消息
非阻塞
指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回
虽然表面上看非阻塞的方式可以明显的提高CPU的利用率,但是也带了另外一种后果就是系统的线程切换增加。增加的CPU执行时间能不能补偿系统的切换成本需要好好评估。
同步
:所谓同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。异步
: 异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列。消息通知
: 异步的概念和同步相对。当一个同步调用发出后,调用者要一直等待返回消息(结果)通知后,才能进行后续的执行;当一个异步过程调用发出后,调用者不能立刻得到返回消息(结果)。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。这里提到执行部件和调用者通过三种途径返回结果:状态、通知和回调。使用哪一种通知机制,依赖于执行部件的实现,除非执行部件提供多种选择,否则不受调用者控制。
阻塞与非阻塞,和同步异步无关,可以阻塞等待同步执行过程完成,也可以阻塞等待异步执行过程完成。根据以上理解, 阻塞与非阻塞/同步与异步是可以相互组合的。
同步阻塞
调用者发起IO操作请求,等待IO操作完成再返回。IO操作的过程需要等待,操作执行完成后返回结果。
同步非阻塞 调用者发起IO操作请求,询问IO操作的状态,如果未完成,则立即返回;如果完成,则返回结果。IO操作的过程需要等待执行完成才返回结果。
异步阻塞 调用者发起IO操作请求,等待IO操作完成再返回。IO操作的过程不需要等待,操作完成后通过通知或回调获得结果。
首先需要明确: 异步操作是可以被阻塞住的,只不过它不是在处理消息时阻塞,而是在等待消息通知时被阻塞。
异步非阻塞 调用者发起IO操作请求,询问IO操作的状态,如果未完成,则立即返回;如果完成,则返回结果。IO操作的过程不需要等待,操作完成后通过通知或回调获得结果。
鄙人很爱看电影,于是乎就拿下载电影来说事儿吧O(∩_∩)O哈哈~
同步体现:等待下载完成通知;
阻塞体现在: 等待下载完成通知过程中,不能做其他任务处理。
同步体现在:等待下载完成通知
非阻塞体现在:等待下载完成通知过程中,去干别的任务了,只是时不时会瞄一眼进度条。
异步体现在:下载完成“叮”一声通知;
阻塞体现在:等待下载完成“叮”一声通知 过程中,不能做其他任务处理;
异步体现在:下载完成“叮”一声通知;
非阻塞体现在:等待下载完成“叮”一声通知过程中,去干别的任务了,只需要接收“叮”声通知即可;[软件处理下载任务,我处理其他任务,不需关注进度,只需接收软件“叮”声通知,即可]
1 | public class BST<E> extends Comparable<E> { |
1 | // 首先将节点压入栈中,如果栈不为空这弹出栈顶元素,并将左右孩子压入栈中,首先压入左孩子然后压入右孩子 |
1 | // 利用队列 |
1 | public class LinkedListStack<E> implements Stack<E> { |
1 | public class LinkedListQueue<E> implements Queue<E> { |
移除链表元素
删除链表中等于给定值 val 的所有节点。示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
1 | public class Solution { |
把递归过程想成一个子函数,在子函数中写处理逻辑来解决上层函数的问题。
1 | public class Solution { |