自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(131)
  • 收藏
  • 关注

原创 本人无意侵权

若有侵权,请联系本人删除。

2021-07-26 10:49:53 89

原创 SO_REUSEPORT正解

SO_REUSEPORT正解最关键的就是多线程负载均衡,多个套接字可以在同一端口上,多个线程可以在各自的套接字上接受自己的数据。Linux 3.9 加入了 SO_REUSEPORT 选项,可以提高 UDP 和 TCP server 的伸缩性,Linux 4.5/4.6 分别进一步改进了 UDP 和 TCP 的 SO_REUSEPORT 实现。本文以 UDP 的实现为例来讲解,TCP 与之类似。UDP 协议的主要数据结构是两张 hash 表,指向 UDP 协议控制块 struct sock。其中 has

2021-08-07 19:02:28 1222

原创 异步IO引擎——io_uring设计与实现

异步IO引擎——io_uring设计与实现转载自 https://zhuanlan.zhihu.com/p/334658432 有改动Linux原来的异步IO有缺陷,现在修复了,在5.x里面引入了io_uring同步IO接口当前Linux对文件的操作有很多种方式,过往同步IO接口,从功能上划分,大体分为以下几种。 - 原始版本 - offset版本 - 向量版本 - offset+向量版本原始版本就是read write,Offset版本是pthread/pwrite(线程安全),向量版本是rea

2021-08-07 16:29:44 818

转载 SO_REUSEADDR

SO_REUSEADDR一个网络应用程序只能绑定一个端口( 一个套接字只能绑定一个端口 )。实际上,默认的情况下,如果一个网络应用程序的一个套接字 绑定了一个端口( 占用了 8000 ),这时候,别的套接字就无法使用这个端口( 8000 ), 验证例子如下:#include <arpa/inet.h>#include <netinet/in.h>#include <stdio.h>#include <stdlib.h>#include <s

2021-07-31 10:25:41 210

原创 对称飞行器

对称飞行器阿里笔试 https://www.nowcoder.com/test/30440638/summary 第4题小强在玩一个走迷宫的游戏,他操控的人物现在位于迷宫的起点,他的目标是尽快的到达终点。每一次他可以选择花费一个时间单位向上或向下或向左或向右走一格,或是使用自己的对称飞行器花费一个时间单位瞬移到关于当前自己点中心对称的格子,且每一次移动的目的地不能存在障碍物。具体来说,设当前迷宫有 n 行 m 列,如果当前小强操控的人物位于点 A(x,y) ,那么关于点 A 中心对称的格子 B(x’

2021-07-29 23:06:05 1247

原创 二叉树方案个数

二叉树方案个数小强现在有n个节点,他想请你帮他计算出有多少种不同的二叉树满足节点个数为n且树的高度不超过m的方案.因为答案很大,所以答案需要模上1e9+7后输出.树的高度: 定义为所有叶子到根路径上节点个数的最大值.例如: 当n=3,m=3时,有如下5种方案:输入描述:第一行输入两个正整数n和m.1<=m<=n<=50输出描述:输出一个答案表示方案数.输入例子1:3 3输出例子1:5输入例子2:3 2输出例子2:1输入例子3:4 3输出例子3:

2021-07-29 20:06:14 585

原创 leetcode 96. 不同的二叉搜索树

96. 不同的二叉搜索树给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?示例:输入: 3输出: 5解释:给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1

2021-07-29 19:50:59 59

原创 小强爱数学

小强爱数学阿里笔试题。测评地址 https://www.nowcoder.com/test/30440638/summary 第二题小强发现当xy=B已知以及x+y=A时,能很轻易的算出x2+y2的值.但小强想请你在已知 A和 B的情况下,计算出xn+yn的值.因为这个结果可能很大,所以所有的运算都在模1e9+7下进行.输入描述:第一行输入一个正整数T.表示有T组数据接下来T行,每行输入三个整数A,B和n.1<=T<=1000<=A,B<=1e9+71<=n&l

2021-07-29 19:25:38 832

原创 leetcode 300. 最长递增子序列

300. 最长递增子序列给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。示例 1:输入:nums = [10,9,2,5,3,7,101,18]输出:4解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。示例 2:输入:nums = [0,1,0,3,2,3]输出:4示例 3:输入:nums

2021-07-28 00:06:31 463

原创 bfs拓扑排序

拓扑排序bfs做法我们使用一个队列来进行广度优先搜索。初始时,所有入度为 0 的节点都被放入队列中,它们就是可以作为拓扑排序最前面的节点,并且它们之间的相对顺序是无关紧要的。在广度优先搜索的每一步中,我们取出队首的节点 u:我们将 u 放入答案中;我们移除 u 的所有出边,也就是将 u 的所有相邻节点的入度减少 1。如果某个相邻节点 v 的入度变为 00,那么我们就将 v 放入队列中。在广度优先搜索的过程结束后。如果答案中包含了这 n 个节点,那么我们就找到了一种拓扑排序,否则说明图中存在环,也

2021-07-27 14:53:10 616

原创 面试题 08.06. 汉诺塔问题

面试题 08.06. 汉诺塔问题难度简单106在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:(1) 每次只能移动一个盘子;(2) 盘子只能从柱子顶端滑出移到下一根柱子;(3) 盘子只能叠在比它大的盘子上。请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。你需要原地修改栈。示例1:输入:A = [2, 1, 0], B = [],

2021-07-27 13:04:37 167

原创 A到B的最少步数

A到B的最少步数A与B地相距n米,一个人第一步只能前进1米或者后退1米,第二步只能前进2米或者后退2米,A走到B最少需要几步测试用例输入2 输出3输入3 输出2解答#include <algorithm>#include <iostream>#include <queue>using namespace std;int main(){ int dis; cin >> dis; int dep = 0;

2021-07-26 20:38:51 455

原创 生成子集笔记

生成子集笔记给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。示例:输入: n = 4, k = 2输出:[ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4],]代码如下dfsclass Solution {public: vector<vector<int>> combine(int n, int k) { vector<vector<int>&gt

2021-07-26 17:43:46 67

原创 nasm demo

nasm demo使用sys_write的hello.asmsection .data msg db "Hello world!",10 ; 10 is the ASCII code for a new line (LF)section .text global _start_start: mov rax, 1 mov rdi, 1 mov rsi, msg mov rdx, 13 syscall mov rax

2021-07-26 15:33:58 131

原创 除法指令demo

除法指令demofpe#include <cstdio>int main(){ int a = 0x80000000; int b = -1; int c = a / b; printf("%d\n", c);}Linux下运行出现Floating point exception (core dumped)查看汇编(gdb) disas mainDump of assembler code for function main(): 0

2021-07-26 15:31:00 193

原创 nasm初步使用

nasm初步使用这篇文章介绍了如何使用nasm开始你的汇编之路,测试平台Ubuntu 18.04。世界上大概没有比写汇编语言更机械性的工作了,如果有,那大概是在期末考试中默写它们。汇编器汇编器是将汇编语言转化为机器码的程序。或许你会以为汇编转化到机器码没什么大不了的,毕竟几乎是一对一的转换。但nasm存在的意义在于它可以很好的适应多种处理器平台,让编写汇编这件事都变得可移植了。nasm可以在Ubuntu下汇编,使用elf32或者elf64格式(具体取决于你的机器,下同)。在不同的机器下写汇编的影响

2021-07-26 15:22:22 3978

转载 通过伙伴系统申请内核内存的函数有哪些?

通过伙伴系统申请内核内存的函数有哪些?在物理页面管理上实现了基于区的伙伴系统(zone based buddy system)。对不同区的内存使用单独的伙伴系统(buddy system)管理,而且独立地监控空闲页。相应接口alloc_pages(gfp_mask, order),__get_free_pages(gfp_mask, order)等。补充知识:多级分页目录结构Linux内核中采 用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64

2021-07-26 13:09:04 202

原创 undo log与redo log原理分析

undo log与redo log原理分析张友东 https://zhuanlan.zhihu.com/p/355744522013年了解事务日志时写的总结文章,最近在研究关系型数据库,重新 review 一下,内容不一定准确,请指正。数据库通常借助日志来实现事务,常见的有undo log、redo log,undo/redo log都能保证事务特性,这里主要是原子性和持久性,即事务相关的操作,要么全做,要么不做,并且修改的数据能得到持久化。假设数据库在操作时,按如下约定记录日志:事务开始时,记

2021-07-26 11:17:56 152

原创 shadow paging wiki

shadow paging wikiIn computer science, shadow paging is a technique for providing atomicity and durability (two of the ACID properties) in database systems. A page in this context refers to a unit of physical storage (probably on a hard disk), typically o

2021-07-26 00:07:13 398

原创 WAL wiki

WAL wikiIn computer science, write-ahead logging (WAL) is a family of techniques for providing atomicity and durability (two of the ACID properties) in database systems. The changes are first recorded in the log, which must be written to stable storage, b

2021-07-25 23:52:28 88 2

原创 binlog wiki

binlog wiki简单来说就是操作记录,以statement为单位20.1 Binary Log Overviewhttps://dev.mysql.com/doc/internals/en/binary-log-overview.html[Some information in this section is derived from Chapter 20, The Binary Log, in the MySQL Reference Manual.]The binary log is a

2021-07-25 23:45:42 60

原创 IA-32函数调用栈帧

IA-32函数调用栈帧//hello.cint add(int x,int y){ return x+y;}int main(void){ int s=11; int b=23; int c=add(b,s); return 0;}反汇编代码m@ubuntu:~$ gcc -S -m32 hello.c -o hello.s -fno-asynchronous-unwind-tablesm@ubuntu:~$ cat hello.s .file

2021-07-25 11:08:41 240

原创 基本汇编指令详解

基本汇编指令详解常见寄存器寄存器16位32位64位累加寄存器AXEAXRAX基址寄存器BXEBXRBX计数寄存器CXECXRCX数据寄存器DXEDXRDX堆栈基指针BPEBPRBP变址寄存器SIESIRSI堆栈顶指针SPESPRSP指令寄存器IPEIPRIP汇编指令movmovb(8位),movw(16位),movl(32位),movq(64位)寄存器寻址:movl %eax,%e

2021-07-25 10:37:49 1101

原创 IA32程序栈帧

IA32程序栈帧(调用者的栈帧)...参数列表返回地址(被调用者的栈帧)---%ebp旧的%ebp保存的寄存器的值局部变量参数列表---%esp当前栈帧也就是被调用者的栈帧,从栈底到栈顶如下构成旧的帧指针(帧指针一般指本栈的栈底,用ebp表示),也就是前一栈帧的ebp指针,它指向前一帧的栈底。保存的寄存器上下文(如果有),因为调用函数寄存器可能有内容,要保存下来,也就是保存在栈上,返回的时候再从栈pop到原来的寄存器。局部变量,即在函数内声明的变量创建的参数列表就是调

2021-07-25 00:22:19 301

原创 栈帧push的汇编解释

栈帧push的汇编解释下面是常见的反汇编代码push %rbpmov %rsp,%rbppush %rbxsub $0x18,%rsppop %rbxpop %rbpretq push %rbp是把%rbp寄存器的值保存到内存里面的数组模拟栈,结合下面的mov %rsp,%rbp可以知道,%rbp此刻pysg的就是上面一个栈帧的栈低位置,同时mov也将本初始化为0长度的栈帧低保存起来,因为此刻rsp是上一个栈帧的栈顶位置,刚好就是我的栈底位置。所以m

2021-07-25 00:00:53 4562 4

原创 多级页表内存

多级页表内存table of table二级页表的内存占用假设虚拟地址空间为32位,即4GB每个页面映射为4KB,以及每条页表项占4B,也就是32位。一级页表管理:一个进程需要使用1M个页表项(=4GB/4KB,2^20),即页表(每个进程都有一个页表)占用4MB(1M*4B=4MB)的内存空间。一级页表管理地址空间如下20 | 12 12代表offset位数,也就是页表的大小4KB。20代表是哪个页表,总共有2^20个页表。这里分割地非常自然。二级页表管理:2^(10+12)=2^2

2021-07-24 16:42:27 1734

原创 多级页表组织

多级页表组织页表在哪里?一般来说,任何进程切换都会暗示着更换活动页表集。Linux内核为每一个进程维护一个task_struct结构体(即进程描述符PCB),task_struct->mm_struct结构体成员用来保存该进程的页表。在进程切换的过程中,内核把新的页表的地址写入CR3控制寄存器。task_struct{ mm_struct mm;}mm_strcuct{ map_count; pgd; mmap;}从pgd得到page global

2021-07-24 16:40:53 121

原创 软中断指令int $0x80的执行过程

软中断指令int $0x80的执行过程它是陷阱类(编程异常)事件,因此它与异常响应过程一样。将IDTi(i=128)中段选择符(0x60,内核代码就是这个表项)所指GDT中的内核代码段描述符取出,其DPL=0,此时CPL=3,因为int $0x80指令在用户进程中执行,因而CPL>DPL且IDTi的DPL=CPL,故未发生13号异常。这里是系统门读TR寄存器,以访问TSS,从TSS中将内核栈的段寄存器内容和栈指针装入SS和ESP。从用户栈切换到内核栈,TSS有内核栈指针,得到内核栈栈顶,可以把用

2021-07-24 12:32:45 2089 1

原创 IA-32/Linux的系统调用

IA-32/Linux的系统调用系统调用(陷阱)是特殊异常事件,是OS为用户程序提供服务的手段。Linux提供了几百种系统调用,主要分为以下类:进程控制、文件操作、文件系统操作、系统控制、内存管理、网络管理、用户管理、进程通信等。系统调用号是系统调用跳转表索引值,跳转表给出系统调用服务例程首地址。调用号名称调用号名称1exit12chdir2fork13time3read19lseek4write20getpid5open3

2021-07-24 12:13:04 175

原创 Linux中对中断的处理

Linux中对中断的处理对于大部分异常,Linux只是给引起异常的当前进程发送一个信号就结束异常处理,具体的异常处理转到信号处理程序进行。对于中断,因为中断事件的发生与正在执行的当前进程很可能没有关系,所以将一个信号发给当前进程没有意义。Linux中有三种类型中断IO中断,IO外设的中断请求。时钟中断,某时钟产生的中断请求,告知固定时间间隔到处理器中断,多处理器系统中其他处理器发出的中断请求IO中断:每个能发中断请求的外设控制器都有一条IRQ线,所有IRQ线连接到一个可编程中断控制器PIC

2021-07-24 11:49:20 419

原创 Linux中对异常的处理

Linux中对异常的处理异常处理程序发送相应的信号给发生异常的当前进程,或者进行故障恢复,然后返回到断点处执行。例如,若执行了非法操作,CPU就产生6号异常(#UD),在对应的异常处理程序中,向当前进程发送一个SIGILL信号,以通知当前进程终止运行。采用向发生异常的进程发送信号的机制实现异常处理,可尽快完成在内核态的异常处理过程,因为异常处理过程越长,嵌套执行异常的可能性越大,而异常嵌套执行会付出较大的代价。并不是所有异常处理都只是发送一个信号到发生异常的进程。例如对于14号页故障异常(#PE)

2021-07-24 11:20:50 1075 1

原创 生成排列详解

生成排列生成[1,2,3]的全排列dfs用来生成排列,但是不彻底理解就完全是在凑巧。wrong case下面代码class Solution {public: vector<vector<int>> permute(vector<int>& nums) { vector<vector<int>> res; vector<int> path; dfs(nums,0

2021-07-22 11:42:01 179

原创 gdb查看继承链内存布局demo1

gdb查看继承链内存布局demo1实验1让我引入两个新的类。一个基类Person和一个从Person继承的派生类Student。请注意,两者都使用其方法who()的相同签名。有了虚函数多态的动态分派后,将查询vtable并调用适当的方法。如果没有虚函数,则将调用与对象的指针类型匹配的方法。 Student *m将调用Student:: who(),而Person *p将调用Person::who()。让我们用汇编代码验证一下。#include <stdio.h>class Pe

2021-07-10 13:01:06 447

原创 模板编译的过程

模板编译的过程太复杂了。以下只是我个人见解,可能有不对的地方。模板只应用于“编译”阶段,就像宏只应用于“预处理”阶段一样。千万别和“链接”阶段和“运行”阶段搞混。我简单说一下函数模板的实例化过程吧。名字查找名字查找,是当程序中出现一个名字时,将其与引入它的声明联系起来的过程。对于模板来说,一个名字可以有多个声明。对于函数而言,这有一个天坑“参数依赖查找”。参数依赖查找可能会引入新的声明,从而可能改变重载集,简直是万恶之源。这里就先不说参数依赖查找了。模板实参推导找到名字的多个声明之后,我们要对函数

2021-07-09 23:24:42 490

原创 传数组防止引用退化

传数组防止引用退化如下定义就得到一个数组的引用类型名 (&变量名)[N];在进行参数的传递时,数组引用可以帮助我们防止数组退化为指针,而这是我们在编程中很难注意到的问题。下面来看一个实例:#include <iostream>void each(int int_ref[10]){ std::cout << sizeof(int_ref) << std::endl; for (int i = 0; i < 10; i++)

2021-07-09 22:36:26 204

原创 时间与并发

并发的本质是时间问题。同步就是force一个时间上的操作顺序。临界区相当于用锁实现的原子性操作。在分布式系统上,Total order是可能顺序世界的一个实例,partial order是加入因果关系后的限制。可见点、生效点、强制点、barrier都是为了规整并发操作的时间顺序。规整性的程度就是区别。通信原语、同步原语本质上是将两个局部的子系统里的时间参考系纳入到上层的时间参考系中。多核CPU是一个分布式系统,内存模型就是一个例子。事务也算是一个并发系统。隔离性的体现。由于跟时间有关,并发的Bu

2021-07-09 21:29:10 153

原创 类型推导精髓

类型推导精髓back to the basic求解未知方程,已知形参和实参,以及一些规则,推最好的那个符合case1形参 T& param实参 int x那么T就是int。形参 T& param实参 const int xT 是const int形参是T& param实参是const int &T 是 const int注意,int类型天然可以转换为int& 类型,而如果位置上有&,那么T自然可以少做这个

2021-07-09 17:58:10 55

原创 std::is_same和std::decay demo

C++11的模板类型判断——std::is_same和std::decay问题提出:有一个模板函数,函数在处理int型和double型时需要进行特殊的处理,那么怎么在编译期知道传入的参数的数据类型是int型还是double型呢?如:#include <iostream>template<typename TYPE>void typeCheck(TYPE data){ //do something check data type //std::cout<

2021-07-09 12:34:25 117 2

原创 SFINAE和enable_if

SFINAE和enable_ifSFINAESFINAE可以说是C++模板进阶的门槛之一,如果选择一个论题来测试对C++模板机制的熟悉程度,那么在我这里,首选就应当是SFINAE机制。我们不用纠结这个词的发音,它来自于 Substitution failure is not an error 的首字母缩写。这一句之乎者也般难懂的话,由之乎者 —— 啊,不,Substitution,Failure和Error三个词构成。我们从最简单的词“Error”开始理解。Error就是一般意义上的编译错误。一旦出

2021-07-09 09:25:26 357 2

原创 cpp中三种多态

cpp中三种多态多态(Polymorphism)是一个大家耳熟能详的概念。在传统的C++教学中,我们通常认为“多态”是函数在类继承体系中所表现出来的一种行为。比如,在下面的例子中,template <typename T> T convertFromInt(int v);void f1() { convertFromInt<float>(5); convertFromInt<double>(5);}struct Base { virt

2021-07-08 21:27:27 856

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除