博客简介

博主

目前就读于华大(University Of Washing)的本科生一枚。只会造个小轮子,偶尔闲着无聊把笔记搬到博客上,顺便理一下知识点。各位大佬有空可去我github瞄一眼,链接右上角。

什么是造轮子?

「造轮子(Reinventing the wheel)」—— 圆形是大家公认的最合适的车轮形状,而有人非要重新再发明一次轮子不但没有意义、浪费时间,还会使其无法投入更有意义及价值的目标。明知道成功的可能微乎其微,而执意去执行的行为就叫造轮子。

为什么要宣扬造轮子精神?

殊不知,造轮子是一种学习方式,能快速通过实践提高自身能力。很多事情看起来简单,但只有自己动手,才会发现其中的难点。想要精通计算机,实践必不可免,没有什么人一出身就站在知识的巅峰。而我希望能宣扬这样一个精神 “明知道你做的不可能比前辈做得更好,却仍然坚持要做。”

阅读更多

数据库内部系统

系统组成

数据库主要分为四大部分: query processor,storage manager,shared utilities 和 Process Manager

query processor

对query进行处理,包括语法,翻译,优化等。由4个功能组件构成

  1. Parser: 检查query 语句的语法
  2. Query Rwrite: 将语句转换成parse tree
  3. optimizer: 只负责优化query,给出query plan。向storage manager 发送数据请求
  4. executor: 当收到storage manager 的数据后,运行query。

transactional storage manager

  1. access methods: 只记录index,维护B+树。
  2. buffer manager: 给disk,main memory,cache memory 分配资源。这三个部分大小,速度,价格都不一样,需要合理分配。
  3. lock manager:负责多线程,确保线程安全
  4. log manager:确保系统发生错误后数据恢复

Process manager

  1. Admission Control: 控制请求数量,确保系统不会过载
  2. connection manager: 负责服务器和客户端的连接

shared utillities

  1. admin utilities : 管理员权限和功能
  2. replication services:为分布式存储的数据库提供同步服务
  3. disk space manager:硬盘空间管理
  4. menory manager:内存空间管理

不同query plan的效率差异

以上图为例,此query plan 将两个表拼接后再进行过滤排序。如果两个表的数据量都很大,拼接会非常耗资源。

进行优化以后, 新的query plan 先过滤一张表,然后进行拼接排序。效率更加高

index

index 是以B+树的形式存储的

使用B+树的优点

未完

虚拟机简介

[返回JVM目录]

此文章为个人简易备忘录,请参考原著《深入了解java虚拟机》

JVM 简介

Java 虚拟机为所有物理机建立了一个统一的运行平台。在任何虚拟机上编译的程序能在任何虚拟机运行,虚拟层面隐藏了底层技术复杂性和操作系统差异性。

阅读更多

类加载

[返回JVM目录]

类加载子系统

由于class文件字节码开头有特定标识,加载子系统可识别。(排除无效文件)
加载器只负责文件加载,Execute engine 决定是否可运行。
字节码实际上是磁盘上的一个文件,要加载到内存当中
常量池在运行过程中加载到内存里就叫做运行时常量池

[返回JVM目录]

运行时数据区域

[返回JVM目录]

数据区

JVM在执行程序时会把内存分为不同的数据区。
各个区域用途不同,有的区域生命周期和进程相同,有的和线程相同。

程序计数器(program counter register)

拥有小块内存空间,显示当前程序字节码文件行号。字节码解释器可以修改此数值,以此选择下一条字节码指令。(循环,跳转,线程恢复等功能)
在JVM多线程中,每一个线程都会有一个独立计数器,确保线程切换后执行位置正确。该内存为线程私有内存,计数器互不影响。

线程执行Java method 时,计数器记录当前字节码位置。执行Naative时,计数器为undefind。此内存区不规定OutOfMemoryError。

虚拟机栈(VM stacks)

该内存也是线程私有,生命周期和线程相同。
虚拟机栈模拟了Java方法执行过程,即栈帧入栈出栈过程: 执行时创建一个栈帧(Stack Frame),储存局部变量,操作数栈,动态链接方法出口信息。

局部变量存储8种基本数据类型,对象引用 和 returnAddress(指向一个字节码指令地址)

本地方法栈

p63

[返回JVM目录]

单列模式 Singleton

饿汉式

类加载到内存后实列化一个单例,JVM保证线程安全
缺点:不论是否用到,都会在类装载时完成实例化
实用但不完美

阅读更多

堆排序 heap sort

概述

  1. 利用堆(heap)设计的一种选择排序
  2. 最坏,最好,平均复杂度为O(nlogn).不稳定排序
  3. 堆类似完全二叉树,左右子节点大小顺序无规定
  4. 大顶堆每个节点大于其左右子节点,
  5. 小顶堆每个节点小于其左右子节点
  6. 一般升序大顶堆,降序小顶堆

流程

  1. 将数组以最大堆重新排序
  2. 将最大值与最小值替换,并移除heap最大值(数组第一位与最后一位交换并缩小范围)
  3. 重复1,2直到剩最后一个

public void sort(int arr[]){
    int n = arr.length;

    // Build heap (rearrange array)
    for (int i = n / 2 - 1; i >= 0; i--)
        heapify(arr, n, i);
    // One by one extract an element from heap
    for (int i = n - 1; i > 0; i--) {
        // Move current root to end
        int temp = arr[0];
        arr[0] = arr[i];
        arr[i] = temp;

        // call max heapify on the reduced heap
        heapify(arr, i, 0);
    }
}

// To heapify a subtree rooted with node i which is
// an index in arr[]. n is size of heap
void heapify(int arr[], int n, int i)
{
    int largest = i; // Initialize largest as root
    int l = 2 * i + 1; // left = 2*i + 1
    int r = 2 * i + 2; // right = 2*i + 2

    // If left child is larger than root
    if (l < n && arr[l] > arr[largest])
        largest = l;

    // If right child is larger than largest so far
    if (r < n && arr[r] > arr[largest])
        largest = r;

    // If largest is not root
    if (largest != i) {
        int swap = arr[i];
        arr[i] = arr[largest];
        arr[largest] = swap;

        // Recursively heapify the affected sub-tree
        heapify(arr, n, largest);
    }
}

假设数组为12 21 13 15 6 17
大顶堆数组移动
12 21 17 15 6 13
12 21 17 15 6 13
12 21 17 15 6 13
21 12 17 15 6 13
21 15 17 12 6 13


替换,重排序,并缩小范围
13 15 17 12 6 21
17 15 13 12 6 21
6 15 13 12 17 21
15 6 13 12 17 21
15 12 13 6 17 21
6 12 13 15 17 21
13 12 6 15 17 21
6 12 13 15 17 21
12 6 13 15 17 21
6 12 13 15 17 21