- 博客(48)
- 资源 (1)
- 收藏
- 关注
原创 nginx四层代理原理
nginx一般使用七层代理也就是http应用层代理,可以反向代理和负载均衡。但是项目要使用长连接,此时内网服务器肯定不能暴漏,还是需要接入层网关进行转发,一般有使用lvs,lvs专门用作四层代理和负载均衡基于内核态,并发量很大。但是lvs配置相对复杂,我们的这个项目长连接数不会太多,所以不需要使用lvs。就直接使用nginx的四层代理,nginx的四层代理需要使用nginx的stream模块在编译...
2020-06-11 00:26:05 8870 1
原创 TCP协议笔记
一、三次握手TCP状态。客户端:1.SYN_SENT 2.ESTABLISHED 服务端:1.SYN_RECVD 2.ESTABLISHED. 1.首先由客户端发起TCP连接,第一个报文段,TCP头部SYN位置为1,随机生成一个ISN, MSS数值(最大报文段 <= 1460),客户端窗口大小,客户端状态变为SYN_SENT。 2.服务端接收到SYN报文段,状...
2019-03-16 23:53:23 561
原创 glibc nptl库pthread_mutex_lock和pthread_mutex_unlock浅析
一、futex简介 futex全称是fast user-space locking,也就是快速用户空间锁,在linux下使用C语言写多线程程序时,在需要线程同步的地方会经常使用pthread_mutex_lock()函数对临界区进行加锁,如果加锁失败线程就会挂起,这就是互斥锁。但是pthread_mutex_lock并不是立即进行系统调用,而是首先在用户态进行CAS操作,判断其它线程是...
2019-03-16 23:46:38 5920 2
原创 从汇编语言看java volatile关键字
一、CPU缓存级别 x86内存变量可以在寄存器中,write buffer中,L1到L3cache中,主存中。寄存器、writebuffer和L1cache或者L2cache是cpu私有的。其中对程序员可编程的是寄存器和主存。cpu如何将变量写到writebuffer和如何写到cache对程序员是透明的。一般cpu读写内存的流程如下: 读内存: ...
2018-11-11 23:05:54 1386
原创 jdk1.8 Unsafe类 park和unpark方法解析
park是Unsafe类里的native方法,LockSupport类通过调用Unsafe类的park和unpark提供了几个操作。Unsafe的park方法如下:public native void park(boolean isAbsolute, long time); 第一个参数是是否是绝对时间,第二个参数是等待时间值。如果isAbsolute是true则会实现ms定时。如果i...
2018-11-03 13:59:04 25359 10
原创 《垃圾回收的算法与实现》 一
一、GC介绍 1.GC就是为了回收对象,对象是GC的基本单位。一般对象由头和域组成 (1)头主要包括对象大小,对象种类和运行GC所需要的信息。 (2) 对象的域就是对象使用者可访问的部分。比如c语言的结构体成员,java的类成员。域主要包括两种指针和非指针。对于java就是引用类型和基本类型。 ...
2018-11-01 14:04:11 1128
原创 jdk1.8 Unsafe类初探
在看java原子类时里有很多方法都调用了Unsafe类方法,Unsafe类方法在jdk里没找到源码,然后下载open jdk找到了源码,在/src/share/classes/sun/misc 目录下。定义如下: public final class Unsafe { private static native void registerNatives(); s...
2018-10-24 01:29:32 2236
原创 红黑树原理及实现
一.二叉搜索树 二叉树是最常用的树形数据结构,二叉树可以分为完全二叉树,满二叉树,平衡二叉树。二叉树应用的最多就是二叉搜索树,二叉搜索树的定义是:设x是二叉搜索树中的一个结点。如果y是x的左子树中的一个结点,那么y.key<=x.key。如果y是x右子树中的一个结点,那么y.key>=x.key。 也就是左子树小于根节点,根节点小于右子树。 普通的二...
2018-10-19 23:01:58 374
原创 Memory Consistency and Cache Coherence —— 内存一致性
随着CPU设计技术的提升,为了加快程序执行有了很多优化技术,1.流水线技术,经典的5级流水线(取指,译码,执行,访存,写回)。2.多发射技术,一个cpu内可以有多个同样的流水线部件,这样就可以在一个周期内发射多条指令,实现指令级并行。3.乱序执行技术,为了避免流水线中断,将不相关(数据相关,控制相关)的指令放到一块进行重新排序,这样可以使得不相关的指令并行执行,比如循环展开技术,指令动态调度技...
2018-10-10 00:18:56 3586
原创 CAS操作在ARM和x86下的不同实现
cmpxchg是X86比较交换指令,这个指令在各大底层系统实现的原子操作和各种同步原语中都有广泛的使用,比如linux内核,JVM,GCC编译器等,cmpxchg就是比较交换指令,了解cmpxchg之前先了解原子操作。 intel P6以及最新系列处理器保证了以下操作是原子的:1.读写一个字节。2.读写16位对齐的字。3.读写32位对齐的双字。4.读写64位对齐的四字。5.读写16位,...
2018-09-27 01:17:08 6001 2
原创 linux内核上下文切换解析
linux的上下文切换就是进程线程的切换,也就是切换struct task_struct结构体,一个任务的上下文包括cpu的寄存器,内核栈等,由于1个cpu上的所有任务共享一套寄存器,所以在任务挂起的时候需要保存寄存器,当任务重新被调度执行的时候需要恢复寄存器。每种处理器都提供了硬件级别的上下文切换,比如x86架构下的TSS段,TSS段包括了一个任务执行的所需要的所有上下文,主要有:1.通...
2018-09-22 00:41:53 2388
原创 TCP协议三次握手和四次挥手抓包分析
TCP协议在双方建立连接的时候需要三次握手,首先客户端发送SYN标志为1的TCP数据包,然后服务器端收到之后,也会发送一个SYN标志置位,并且带有ack应答的数据包,最后客户端再发送给服务端一个应答,这样就建立起了通信。 首先看TCP数据包头部各个字段: 在三次握手和四次挥手过程中,主要看UAPRSF6个标志和seq ack的变化。首先使用telnet程序测试,比如tel...
2018-09-02 20:23:47 16786 1
原创 linux内核进程创建fork源码解析
平时写过多进程多线程程序,比如使用linux的系统调用fork创建子进程和glibc中的nptl包里的pthread_create创建线程,甚至在java里使用Thread类创建线程等,虽然使用问题不大,但需要知道底层原理。这次在自己写操作系统的时候,看了一遍linux内核的进程创建过程。算是有了比较深入的理解。 进程概念:进程是对正在运行程序的一个抽象。一个进程就是一个正在执行...
2018-08-20 23:25:51 2186
原创 linux内核缺页中断处理
现代处理器大部分都有MMU,除了一些小型嵌入式设备。MMU可以做虚拟地址到物理地址的转换,使用MMU我们就可以使用更多的内存空间,因为程序具有局部性原理,我们可以将暂时用不到的数据存放到磁盘,当访问到时会发生缺页中断,从磁盘中将所需要的数据加载到内存。所以我们可以通过mmu运行程序大小大于内存的程序和打开大于内存的文件。现代处理器通过分段分页机制实现虚拟地址到物理地址转换一般支持二级页表或四级页表...
2018-07-12 22:56:58 6016 2
原创 linux进程虚拟空间布局
首先看linux进程的虚拟空间内存布局,以i386 32位机器为例每个用户进程的虚拟地址空间为0x0—0xC0000000也就是3GB,其中0x0—0x08000000 128MB地址空间用于捕获空指针,用户空间分为代码段,堆,mmap区,栈。堆的起始地址start_brk依据代码段和数据段的大小确定,堆从低地址往高地址增长,mmap区从高地址往低地址增长当两个区域相撞时则区域耗完,mmap区基地...
2018-07-02 23:10:50 1388
原创 Memory Consistency and Cache Coherence—— cache一致性协议(MESI)
cache监听一致性主要是获得cache的总线访问权,比如core1和core2同时写入相同的地址,会交由总线进行仲裁,确定哪个核先写入,在获得写入权限后,会通过总线广播使地址失效。一般的smp架构cpu cache结构如下图:其中分为三级cache,第一级和第二级cache是处理器独有的,第三级cache是共享的,L1cache分为指令cache,数据cache。intel co...
2018-06-15 17:53:13 1682
原创 重写equals方法必须重写hashcode
equals方法定义在java的根类Object类,定义如下public boolean equals(Object obj) { return (this == obj);}比较的是引用,也就是对象的地址是否相等,equals在非空对象上需要满足以下特性:1.自反性:x.equals(x) == true,自己和自己比较相等2.对称性:x.equals(y) == y.equa...
2018-06-12 13:47:55 2087
原创 jdk1.8源码阅读PriorityQueue
PriorityQueue是优先队列,可以按照指定的优先级进行排序,比如某个元素优先级最高,当它插入队列时会被插到队列头。jdk优先队列是通过二叉堆实现的,类似堆排序,根节点始终是优先级最高的元素,父结点的优先级要高于左右孩子结点,优先队列的调整时间复杂度是O(logn)。包括从上往下调整和从下往上调整,以满足二叉堆的性质。PriorityQueue的类关系图如下: package ...
2018-06-07 21:19:29 382
原创 jdk1.8源码阅读LinkedList
LikedList实现采用了双向链表,并且LinkedList实现了Dqueue接口,所以LinkedList可以当作普通队列和双端队列使用,首先看一下LinkedList的类关系图LinkedList和ArrayList的区别就是继承了AbstractSequentialList,并且实现了Dqueue接口,AbstractSequentialList和AbstractList的主要区别是采用迭...
2018-05-29 23:58:08 273
原创 jdk1.8源码阅读ArrayList
ArrayList的实现原理就是大学数据结构书本中的动态数组原理,初始化一个Object数组,然后对Object数组进行插入,扩容,查找,删除等操作。所以可以看出java引用类型所占内存大小是一样的,Object数组类似于c语言中的void*指针数组,每个指针在64位机器上都占8字节, 在hotspot jvm中java引用类型也是占8字节。所以ArrayList无法存放基本类型,只能存放引...
2018-05-28 23:42:02 317
原创 leetcode 3. Longest Substring Without Repeating Characters---最长不重复子串 C语言版 faster 100%
最长不重复子串,abcabcbb 则最长的不重复子串是3,abc。 bbbbb 最长不重复子串是b,长度为1,pwwkew最长子串是wke或者kew 为3.解法一:暴力解法 遍历每一个字符串,以次字符串为开头求最长的不重复长度,最后取出最大的,复杂度是O(N^3).int lengthOfLongestSubstring(char* s) { int max ...
2018-03-05 22:38:42 258
原创 Memory Consistency and Cache Coherence——内存连贯性和cache一致性 (1)
并行包括指令级并行,数据级并行,线程级并行。指令级并行主要是在一个CPU内利用流水线,乱序执行,指令多发射等技术实现。线程级并行主要利用多核cpu。指令级并行对程序员是透明的,完全靠硬件实现。 多处理器体系结构主要有两类,第一类是对称多处理器(SMP),特点是核心数目较少,通常不超过8个,这些处理器共享一个集中式存储器,所有处理器平等访问存储器。SMP也称为一致存储器访问(UMA)多处
2017-09-05 10:22:52 2792
原创 linux内存管理slab算法之kmem_cache结构创建
kmem_cache是slab的核心结构体,主要描述slab的各种信息和链接空闲slab,还保存高速缓存的指针数组。所以要想使用slab分配得先创建kmem_cache结构体。struct kmem_cache *kmem_cache_create (const char *name, size_t size, size_t align, unsigned long flags, void
2017-08-31 11:39:00 3627
原创 linux内存管理slab算法之slab初始化
业余时间写的玩具操作系统,准备把内存管理部分加强一下,伙伴系统分配页面算法已经完成,下面就要开始写更加细粒度的内存分配,毕竟伙伴系统是按照页为基本单位分配的,参考内核版本linux2.6.30,没分析高版本的源码,算法基本思想应该差不多。 slab算法是一个高效的内存分配算法,它通过把经常使用的内存块比如32字节,64字节大小或者某个常用结构体大小的类型组织成一个kmem_cache结构
2017-07-31 17:34:26 508
原创 内存分配算法 伙伴系统
#include #include #include #include //双向链表struct list_head { struct list_head *prev, *next;};//拉链法存储空闲内存typedef struct free_area { struct list_head free_list; //把空闲内存块链接到空闲链表 uns
2017-06-22 12:50:22 1028
原创 算法学习之哈希表实现
哈希表是一个键值对的数据结构,经常用于数据库索引,map,缓存等地方。可以表示成value = f(key),查找效率很高。哈希表实现最关键的地方是哈希函数的选择,好的哈希函数可以均匀分布,冲突小。现在工业界最常用的哈希函数是murmur,memcached和nginx使用的就是murmur。简单常用的哈希函数构造法有:1.直接定值法,利用key设计一个线性函数 f=a*key+b; 2.数字分析
2017-05-23 14:20:18 417
原创 同步图计算框架GraphLite编程之图着色
GraphLite github地址 https://github.com/schencoding/GraphLite 图很适合进行分布式并行计算,比如最短路径,PageRank等问题,比较著名的图计算框架有Prege,cmu的GraphLab,apache的Giraph等。GraphLite属于BSP模型。BSP模型如下图: 也就是超步计算,apache
2017-05-06 22:59:26 1943
原创 hadoop编程之mapreduce,计算总数和平均数
import java.io.IOException;import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.Path;import org.apache.hadoop.io.Text;import org.apache.hadoo
2017-05-06 22:41:02 2039
原创 hadoop读写hdfs和操作hbase,把hbase内容按group by排序
package org.ucas.hbase;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.URI;import java.net.URISyntaxException;import java.util.HashMap;
2017-05-06 22:30:44 4385
原创 操作系统之x86架构下的bootloader
bootloader主要做四件事,1.开启A20地址线;2.探测内存,把内存相关信息告诉内核;3.初始化全局描述符表,开启分段机制,进入保护模式;4.把操作系统内核从磁盘加载到内存指定位置,跳转到内核,执行内核代码。1.开启A20地址线,把内存寻址扩展到4GB。enable20.1: inb $0x64, %al t
2017-05-06 21:49:14 1634
原创 操作系统学习之BIOS
在x86架构的机器中,有一块ROM,里面存放了BIOS程序,BIOS程序就是开机自检程序,初始化内存控制器,中断控制器,设置中断向量等,将系统软硬件带到一个合适的状态,为操作系统内核准备环境。在ARM架构中没有BIOS,但是得自己写bootloader,bootloader一般存放在flash内,起始地址一般为0x00000000。下面看一下x86架构启动方式。 8086是16位机器,
2016-08-14 19:00:15 2706
原创 windows下mysql5.7安装遇到的问题
windows下Mysql安装完第一次进入的时候显示ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO); 解决办法:1.修改mysql安装目录my.ini文件,最后一行添加skip-grant-tables 2.重启mysql服务
2016-08-07 01:04:21 306
原创 leetcode26. Remove Duplicates from Sorted Array
这道题就是从一个有序的数组中删除重复的元素,然后返回删除后的数组长度。这道题主要使用两个指针,一个指针指向待比较元素,另一个迭代数组,如果一样往后走,如果不一样,则把数字放到待比较元素的后一个位置。class Solution {public: int removeDuplicates(vector& nums) { if(nums.empt
2016-05-12 23:34:23 259
原创 算法学习之素数环问题
1-n组成的素数环,素数环就是一个数组中后一个数加前一个数必须组成素数,a[i]+a[i-1]是素数,又因为是环状所以,首末相加也要上素数即a[0]+a[n-1]是素数,因为是环状所以会有很多重复的排列,我们要除去重复的排列,就要假定所有的排列都以1打头。我们也是用回溯加剪枝来求素数环#include #include using namespace std;unsigned char v
2016-03-25 14:50:09 653
原创 算法学习之8皇后问题
8皇后问题是高斯提出来的一个问题,在一个8*8棋盘上,8个棋子不在同一行同一列,和同一个对角线上的摆放方式有几种,我们一般才有回溯加剪枝的方法求解。回溯剪枝法也是很多公司笔试题中简单题经常考的。#include #include #include #include #include using namespace std;int arry[8][8]; //打印数组用的int t
2016-03-25 12:19:11 725
原创 算法学习之子集生成问题
在暴力求解算法中,子集生成问题是一个很重要的算法,在一个数组中找到各种子集,然后筛选出符合题目条件的子集,比如n-sum等问题,现在写一个位向量法生成子集的通用模板#include #include #include #include using namespace std;/*visit是一个标记数组,判断是否选择该位置的数*/void create_subset(vector &a
2016-03-25 10:36:26 769
原创 算法学习之最长公共子串
最长公共字串,最长公共子序列,最长递增子序列都是典型的动态规划问题,最长公共子串和最长公共子序列的差别是最长公共子序列可以不连续,但是最长公共子串必须连续。先来看最长公共子串,首先会想到暴力法解决,最长公共子串的暴力法会达到指数级,所以我们直接用dp解决,先确定状态,由于最长公共子串必须是连续的,所以我们这个状态很好想出来,dp[i][j]代表字符串str1位置i之前和str2位置j之前公共子串多
2016-03-18 16:01:00 865
原创 寻找大小为n的数组中出现次数超过n/2的那个数
问题描述: 在一个大小为n的数组中,其中有一个数出现的次数超过n/2,求出这个数。这题看似很简单,但是找到最优解不容易,一般情况我们首先想到最笨的方法,每选一个数,遍历一次数组,复杂度O(N^2),或者先排序再找那个数,复杂度一般为O(NlgN),或者用hash,时间复杂度O(N),空间复杂度需要看输入的数据规模,空间复杂度O(N)。所以这些都不是最优解,我们先分析一下这个题目,设该数出现的次数为
2016-03-14 15:21:46 7838
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人