摘要: 这次不以面试背题为目的,挑几个源码实现中值得玩味的点来分析一下。 首先看几个初始化参数,在实现中 Lea 大爷大量的使用了二进制位移运算。比如 16 表示为 1<<4 ,1 073 741 824 表示为 1<<30 。由于计算机的物理特性,二进制运算的效率尤其是位移运算是高于直接使用十进制运算的。 阅读全文
posted @ 2020-07-27 15:58 牛新宇 阅读(488) 评论(1) 推荐(0) 编辑
摘要: JS 是单线程的。 JS 是一门解释型脚本语言,主要用于处理浏览器与用户的交互。 个人认为设计为单线程的考量在于: 1、绝大多数交互相关的任务都是 CPU 密集型的短任务,任务耗时短、CPU 占用率高。若使用多线程,线程调度开销占总开销的百分比过大,收益不高。 2、要频繁的处理 DOM 元素。在所有 阅读全文
posted @ 2020-07-23 22:39 牛新宇 阅读(180) 评论(0) 推荐(0) 编辑
摘要: 如果我们要将一个文件通过 socket 发送出去,我们一般会这样写: Socket socket = new Socket(); socket.connect(new InetSocketAddress("127.0.0.1", 33456),10 * 1000); DataOutputStream 阅读全文
posted @ 2020-04-20 14:02 牛新宇 阅读(310) 评论(0) 推荐(0) 编辑
摘要: 想要理解多路复用技术,首先要了解这个技术出现之前,我们面临的痛点是什么。 以 JAVA 为例,我们想要写一个 TCP 服务端,接收客户端发来的数据,那么我们会这样写: while (true) { Socket socket = serverSocket.accept(); //读取输入缓冲区数据 阅读全文
posted @ 2020-04-14 23:57 牛新宇 阅读(335) 评论(0) 推荐(1) 编辑
摘要: 在使用微服务的过程中,RPC 是永远绕不开的点。之前并没有磕的很深,一直觉着 RPC 是一个黑魔法。比如我们常用的 Dubbo、SpringCloud 等框架,将微服务模块间的方法调用封装的像本地方法调用一样,方便又令人费解。 今天如愿以偿的仿照 Dubbo 自己手写了一个 rpc “框架”,虽然简 阅读全文
posted @ 2020-03-24 11:27 牛新宇 阅读(383) 评论(0) 推荐(0) 编辑
摘要: 前面的博客 基于 socket 手写一个 TCP 服务端及客户端 写过一个简单的 TCP 服务端客户端,没有对代码结构进行任何设计,仅仅是实现了相关功能,用于加深对 socket 编程的认识。 这次我们对整个代码结构进行一下优化,使其模块化,易扩展,成为一个简单意义上的“框架”。 对于 Socket 阅读全文
posted @ 2020-03-22 18:44 牛新宇 阅读(477) 评论(0) 推荐(0) 编辑
摘要: 池化是我们在实际生产中经常用到的一种思想,通过一个 “池” 把资源统一的管理起来。可以达到对资源的合理管理、重复利用、减少资源创建/销毁的开销等目的。 常见的比如常量池、连接池、线程池,今天我们手撸一个线程池。 抛开语言特性,线程池无非是维护一堆线程阻塞等待任务的到来,并由主线程对任务线程的数量进行 阅读全文
posted @ 2020-03-14 23:33 牛新宇 阅读(2780) 评论(0) 推荐(0) 编辑
摘要: 数据一致性部分借用大神“耗叔”的博客:https://coolshell.cn/articles/20793.html。 总结:volatile 关键字通过内存屏障禁止了指令的重排序,并在单个核心中,强制数据的更新及时更新到缓存。在此基础上,依靠多核心处理器的缓存一致性协议等机制,保证了变量的可见性 阅读全文
posted @ 2020-03-02 19:00 牛新宇 阅读(2653) 评论(2) 推荐(1) 编辑
摘要: 文章篇幅较长,知识点涵盖比较广泛,作为学习 JS 的一个总结。文章中仅涵盖 ES5 及之前的传统的知识点,未涵盖 ES6 及之后的新特性。 JavaScript(简称“JS”) 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名的,但是它也被用到了很 阅读全文
posted @ 2020-02-04 17:54 牛新宇 阅读(386) 评论(0) 推荐(1) 编辑
摘要: 前言 学习 λ 演算的初衷是为了更好的使用 JAVA8 的 lamda表达式,但是在学习过程中发现 λ 演算的作用和深度远远比想象的大的多得多。λ 演算的定义并不复杂,包括一条变换规则(变量替换)和一条函数定义方式,但其外延却囊括和渗透到了无数方向,乃至学习过程中脑中不断冒出一句话:内涵越小、外延越 阅读全文
posted @ 2020-01-31 21:50 牛新宇 阅读(652) 评论(0) 推荐(1) 编辑
摘要: 《深入理解计算机系统》学习笔记与总结 首先一个大的总结:在计算机中,使控制流发生突变的源头被称为异常控制流。异常是分为多个层级的,硬件异常与软件异常。我们在讨论异常的处理时也应该分情况讨论。异常控制流存在的逻辑是:我们的程序除了需要对程序内部状态的变化做出反应外,也应该可以对系统状态的变化做出反应。 阅读全文
posted @ 2019-12-25 20:49 牛新宇 阅读(1321) 评论(0) 推荐(1) 编辑
摘要: 时序电路 首先来看两个问题: 1.为什么CPU要用时序电路,时序电路与普通逻辑电路有什么区别。 2.触发器、锁存器以及时钟脉冲对时序电路的作用是什么,它们是如何工作的。 带着这两个问题,我们从头了解一下逻辑电路。要了解逻辑电路,首先我们便要了解组成逻辑电路的基本单位:逻辑门。 逻辑门 逻辑门是数字电 阅读全文
posted @ 2019-12-21 00:13 牛新宇 阅读(1706) 评论(0) 推荐(0) 编辑
摘要: 第一节 哲学家就餐问题 第二节 什么是死锁 第三节 死锁的定义 第四节 死锁发生的条件 第五节 如何避免死锁 5.1 动态避免,银行家算法(杠杆分配),在资源分配上下文章 5.2 静态避免,从任务代码上避免死锁 第六节 死锁的综合治理 第一节 哲学家就餐问题 假设有五位哲学家围坐在一张圆形餐桌旁,做 阅读全文
posted @ 2019-12-08 22:25 牛新宇 阅读(2255) 评论(1) 推荐(6) 编辑
摘要: 这道题目做了两个晚上,发现解题思路的优化过程非常有代表性。文章详细说明了如何从回溯解法改造为分治解法,以及如何由分治解法过渡到动态规划解法。解法的用时从 超时 到 超过 95.6% 提交者,到超过 99.8% 提交者。现整理下来分享给大家,如有错误评论区欢迎指正! 题目如下: 回溯法 刚看到这个题目 阅读全文
posted @ 2019-12-02 14:58 牛新宇 阅读(2178) 评论(2) 推荐(3) 编辑
摘要: 前言 中断的概念属于硬件层。虽然在进行软件编程时不会直接使用中断,但理解它对我们来说依然重要。 在使用线程切换及状态管理、异常处理、硬件与处理器的交互、I/O操作等指令时,中断都在默默的服务。 处理器基于硬件封装对外的指令集,底层语言封装指令集提供更加简单的抽象,高级语言基于底层语言赋予程序更明确的 阅读全文
posted @ 2019-11-21 19:50 牛新宇 阅读(9457) 评论(0) 推荐(2) 编辑
摘要: 针对 docx ,处理正文、表格、标头中的坐标替换。 public static void copyAndReplace(String oldPath, String newPath, Map<String, String> dict) throws Exception { FileOutputSt 阅读全文
posted @ 2021-10-30 15:08 牛新宇 阅读(64) 评论(0) 推荐(0) 编辑
摘要: 在项目中,为了节约网络消耗,需要将文件进行压缩后上传服务端。 最开始考虑的是将文件压缩为 zip ,由服务端返回后前端 zip 再进行解压。但 zip 对小文件、图片、视频的压缩效果很差。所以需要多种压缩方式配合使用。 图像采用 canvas 有损压缩: utils.dealImage = (bas 阅读全文
posted @ 2021-10-22 15:54 牛新宇 阅读(49) 评论(0) 推荐(0) 编辑
摘要: springboot 中 @NotNull 等参数检查注解非常实用,优化掉了很多的重复代码。 在开发老版本 spring 项目时,没有类似注解,所以自己实现一个类似的功能,优化代码结构。 由于项目中没有使用统一异常处理,注解用于 Service 层,抛出的异常由 Controller 处理。 首先自 阅读全文
posted @ 2021-10-03 22:47 牛新宇 阅读(59) 评论(0) 推荐(0) 编辑
摘要: 场景:页面包含多个大 sql。 目的:尽量保证接口响应速度,数据库压力可暂不考虑(并发不大,耗时 sql 多)。 思路: 1、如果 redis 中不存在缓存,查询数据库并添加缓存,根据数据变化频率设置缓存过期时间; 2、如果 redis 中存在缓存,提交更新缓存的异步任务(可选,针对数据变化频率高, 阅读全文
posted @ 2021-09-27 23:21 牛新宇 阅读(21) 评论(0) 推荐(0) 编辑
摘要: 手写分布式锁,仅适用于单例 Redis。 与多线程的加锁解锁机制一样,分解出加锁解锁需要做的动作后,想办法保证动作的原子性即可。 X86 架构提供了 getAndSet 原语,保证了锁的检查与上锁这组动作的原子性,操作系统在其基础上提供了非常多的加锁方法。 Redis 也提供了类似的 “原语”:SE 阅读全文
posted @ 2021-09-27 11:07 牛新宇 阅读(29) 评论(0) 推荐(0) 编辑
摘要: JAVA: public final int[] topKFrequent(int[] nums, int k) { Item[] arr = this.initItemArr(nums); HeapSort heap = new HeapSort(arr); int[] reArr = new i 阅读全文
posted @ 2021-09-08 10:46 牛新宇 阅读(26) 评论(0) 推荐(0) 编辑
摘要: Promise 的作用是优化异步操作,解决“回调地狱” 问题。 对于异步操作,可以将其封装为 promise 对象,通过链式调用替代回调函数的嵌套。例如: let print = function (msg) { return new Promise((resolve, reject) => { t 阅读全文
posted @ 2021-08-16 22:44 牛新宇 阅读(45) 评论(0) 推荐(0) 编辑
摘要: JAVA: public final boolean canCross(int[] stones) { int len = stones.length; return jump(stones, 0, 0, new HashMap<Long, Boolean>()); } private final 阅读全文
posted @ 2021-07-24 21:28 牛新宇 阅读(24) 评论(0) 推荐(0) 编辑
摘要: JAVA DP 反向: public final int maximalSquare(char[][] matrix) { int xLen = matrix.length, yLen = matrix[0].length, re = 0; int[][] cache = new int[xLen] 阅读全文
posted @ 2021-07-22 23:24 牛新宇 阅读(18) 评论(0) 推荐(0) 编辑
摘要: JAVA DP: public final boolean wordBreak(String s, List<String> wordDict) { Set<String> set = new HashSet<String>(); for (String word : wordDict) set.a 阅读全文
posted @ 2021-07-13 23:55 牛新宇 阅读(13) 评论(0) 推荐(0) 编辑