摘要:
暴力法没有什么技术含量,但暴力法包含着我们对解空间最基本但认识。不管什么题目,还是习惯最先用暴力的思路考虑一遍,再去考虑优化方式。 //最终结果 int an = 0; //路径计数 int tar = 0; public int deleteAndEarn(int[] nums) { tar=nu 阅读全文
摘要:
/** * @Author Niuxy * @Date 2020/6/10 9:42 下午 * @Description 多 selector 多线程的 NIO 服务端 * 使用 NIO 时一定要摒弃 BIO 的阻塞思维,我们的代码面向的是事件,而不是连接 * 至于多次事件完成一个连接的情况,我们可 阅读全文
摘要:
直接上源码,查看 register 的实现。我们查看 register 的实现会直接跟进抽象类 SelectableChannel 中: 调用了本身的另一个 register 方法: 该实现为抽象方法,我们直接向下查找 SelectableChannel 子类,查看其实现。因为 SocketChan 阅读全文
摘要:
在多道编程的情况下,想要保证线程按我们预想的方式协作,抛开原子性、可见性、有序性的概念,白话总结下心得: 1. 从涉及到操作共享数据的指令入手,保证它们对共享数据操作的正确性。 2. 首先保证单线程情况下,程序执行的正确性。然后判断线程中,与操作共享变量的指令存在数据依赖的指令构成的指令集。保证指令 阅读全文
摘要:
最近工作比较忙,水一篇: /** * @Author Niuxy * @Date 2020/6/8 8:54 下午 * @Description 基于双向链表的简单 FIFO 队列 * 锁的粒度很粗,仅针对最上层操作进行互斥同步关系规划 * 最上层方法有两个:put 与 remove * 以 len 阅读全文
摘要:
LRU(最近最少使用) 缓存为一段固定大小的缓存,按最近最少使用的淘汰策略对数据进行管理。 一个 LRU 缓存应当支持 put 和 get 操作: 进行 get 操作时,发生 cache miss 返回固定标识。缓存命中在返回数据的同时更新最近使用时间。 进行 put 操作时,如果 key 存在则更 阅读全文
摘要:
众所周知,JVM 创建一个对象分三步: 1.在堆内存开辟内存空间。 2.在堆内存中实例化Car里面的各个参数。 3.把对象指向堆内存空间。 为了提高运行效率,编译器在编译代码时可能会对指令进行重排序。重排序的原则是,保证单线程执行结果的正确性,并遵循 happen-before 原则。 指令间的依赖 阅读全文
摘要:
Reactor 模型不再介绍,网上有很多。在实现的过程中有一些收获: 1. Reactor 广义上说,事件发生时便会触发为事件注册的处理函数。在注册感兴趣的事件时,需要将处理函数一并绑定到事件上,在 NIO 中我们通过 SelectionKey 的 attachment 携带函数对象。 2. 使用 阅读全文
摘要:
在 NIO 中,我们读取 channel 中的数据,会通过 channel 的 read 尽最大努力将 Buffer 填满,填满后做一些其它处理。 对于 TCP 协议来说,这种做法无可厚非,因为 TCP 协议本身就不提供定界策略,只负责提供可靠的连接,也就是数据可靠的收发( 以 ack 应答机制为核 阅读全文
摘要:
水平触发(level-triggered,也被称为条件触发)LT:只要满足条件,就触发一个事件。边缘触发(edge-triggered)ET:当状态变化时触发事件。JAVA 的 NIO 属于水平触发,而 epoll 既支持水平触发也支持边缘触发。epoll 性能高于 poll 很重要的一点便是 ep 阅读全文