Blog

toc:Java

Core #

JVM #

指令 #

函数式编程 #

新特性 #

sub:GC Class File Versions

TLB

Content #

TLB是translation lookaside buffer的简称。TLB缓存虚拟地址和其映射的物理地址。虚拟地址首先发往TLB确认是否命中cache,如果cache hit直接可以得到物理地址。否则,一级一级查找页表获取物理地址。并将虚拟地址和物理地址的映射关系缓存到TLB中。

Viewpoint #

From #

投机执行

Content #

CPU对分支指令进行预测,对于可能会执行的分支可以提前投机执行。如果预测错误,执行结果就不commit,如果预测正确,性能会有很大的提升。

相关阅读:gcc内建宏_likely_, unlikely

Viewpoint #

From #

乱序窗口

Content #

CPU会使用乱序窗口(ReOrdering Buffer, ROB)一次性取多条指令,并判断指令之间是否存在数据依赖,结构冲突。没有依赖和冲突的指令可以一起发射。所以编译器指令调度的重要性有所下降。

Viewpoint #

From #

只出现一次的数字III

只出现一次的数字 III #

https://leetcode.cn/problems/single-number-iii/

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。

进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?

示例 1:输入:nums = [1,2,1,3,2,5] 输出:[3,5] 解释:[5, 3] 也是有效的答案。

示例 2:输入:nums = [-1,0] 输出:[-1,0]

示例 3:输入:nums = [0,1] 输出:[1,0]

提示: 2 <= nums.length <= 3 * 104 -231 <= nums[i] <= 231 - 1 除两个只出现一次的整数外,nums 中的其他数字都出现两次。

Answer #

  1. 将所有数异或
  2. 假设最后所求两数是m和n,则最后的结果a就是m xor n,一定不为0。
  3. 找到 a 的最低一位 1,然后将原数据分为两组,一组该位为1,另一组该位为0,则 m 与 n 一定分属两个不同组。
  4. 两组分别进行异或操作。
class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int x = 0;
        for (int n : nums) {
            x ^= n;
        }
        int d = x == INT_MIN ? x : x & (-x);
        int x1 = 0, x2 = 0;
        for (int n : nums) {
            if ((d & n) == 0) {
                x1 ^= n;
            } else {
                x2 ^= n;
            }
        }
        return {x1, x2};
    }
};

Viewpoint #

From #

只出现一次的数字

只出现一次的数字 #

https://leetcode.cn/problems/single-number/

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1: 输入: [2,2,1] 输出: 1 示例 2:

输入: [4,1,2,1,2] 输出: 4

Answer #

a xor a 的结果为0。异或操作还满足结合律与交换律。因此,只要把把有元素异或一次就得到结果。

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int res = nums[0];
        for (int i = 1; i < nums.size(); i++) {
            res ^= nums[i];
        }
        return res;
    }
};

Viewpoint #

From #

8位字节对齐

Content #

8位字节对齐,用C语言可描述如下:

char* p;
(p & -8)

假定数据为1字节,-8的二进制表示为: 1111000

Viewpoint #

From #

toc:Distributed

基本概念 #

时钟 #

物理时钟与逻辑时钟 常见授时方案 TrueTime授时机制 TSO授时机制 HLC授时机制

分布式协议 #

二阶段提交协议的四个缺点 分布式2PC事务延迟估算 什么是TCC 如何通过TCC指令执行的原子性 TCC与XA规范的区别 Percolator的流程 Percolator对2PC的改进

Paxos #

三种角色 Basic Paxos 达成共识的过程 接受者保证三个承诺 多次执行BasicPaxos的缺陷及解决方案 Multi-Paxos无法保证操作顺序性

Raft #

顺序投票对复制性能的影响 Raft服务器节点的三种状态 选举领导者的过程 什么是任期 日志完整性优先 Raft日志格式 日志复制将二阶段优化成了一阶段 日志复制过程 如何实现日志的一致 随机超时时间的两种含义

一致性 #

状态视角与操作视角 写后读一致性 单调读一致性 前缀一致性 线性一致性 因果一致性 数据一致性与事务一致性

Quorum NWR #

Quorum NWR三要素 如何选择Quorum NWR的三个参数

分片 #

Hash分片 一致性Hash 一致性哈希算法 一致哈希如何避免哈希算法的缺陷 TiDB分片元数据的存储方案 CockroachDB分片元数据存储方案

服务部署的五种模式

Content #

在分布式系统的世界里,一个服务有多个实例,所以部署或是升级一个服务也会变得比较麻烦。服务部署的模式,一般有哪五种?

  1. 停机部署(Big Bang / Recreate): 把现有版本的服务停机,然后部署新的版本。
  2. 蓝绿部署(Blue/Green /Stage):部署好新版本后,把流量从老服务那边切过来。
  3. 滚动部署(Rolling Update / Ramped): 一点一点地升级现有的服务。
  4. 灰度部署(Canary):把一部分用户切到新版本上来,然后看一下有没有问题。如果没有问题就继续扩大升级,直到全部升级完成。
  5. AB 测试(A/B Testing):同时上线两个版本,然后做相关的比较。

Viewpoint #

From #

Docker如何管理init层

Content #

Docker镜像文件系统中以“-init”结尾的层是用来存放什么信息的?Docker管理init层有何特殊处理?

以“-init”结尾的层,夹在只读层和读写层之间。Init 层是 Docker 项目单独生成的一个内部层,专门用来存放 /etc/hosts、/etc/resolv.conf 等信息。需要这样一层的原因是,这些文件本来属于只读的 Ubuntu 镜像的一部分,但是用户往往需要在启动容器时写入一些指定的值比如 hostname,所以就需要在可读写层对它们进行修改。可是,这些修改往往只对当前的容器有效,我们并不希望执行 docker commit 时,把这些信息连同可读写层一起提交掉。所以,Docker 做法是,在修改了这些文件之后,以一个单独的层挂载了出来。而用户执行 docker commit 只会提交可读写层,所以是不包含这些内容的。

Viewpoint #

From #