自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

Life runs on code

做最好的自己

  • 博客(153)
  • 资源 (2)
  • 收藏
  • 关注

原创 Go语言模型:通过runtime源码和汇编看interface的底层实现

Go的汇编要看懂Go的内存模型,就需要对Go runtime的源码和Go的汇编指令有一定的了解。Go的汇编是基于 Pan9 汇编的风格,。Go的runtime源码中有大量的汇编,比如goroutine的上下文切换肯定是要汇编的,切换栈帧和寄存器,这些是无法通过简单的function call来完成的,操作系统的线程上下文切换同样类似。在Linux平台,我们通过Go runtime的源码和GDB...

2018-11-19 00:07:45 1199

原创 C语言侵入式链表

C语言虽然没有泛型,但是拥有对内存的终极解释权限,这个也带给了C语言强大的表达能力。对于复杂数据结构,侵入式链表绝对是一个好的经典实现,Linux Kernel 在 2.1 之后就使用 list_head 的内嵌来实现双向循环链表。而且,glibc也提供了这种实现的标准库 glibc/include/list.h。对于C语言项目,有时候会需要精细规划内存使用。这时设计数据结构时,通常都是存储和控...

2018-10-26 23:38:28 2050 1

原创 C语言用结构体给另一个同类型结构体赋值: 用等号即可

看到很多C代码的结构体赋值都是用memcpy函数来拷贝,其实根本不需要,用等号直接赋值即可。结构体描述的是的一块连续内存的内存布局,用等号来用一个结构体给另一个结构体赋值,编译不会有任何问题,其效果显然也和人直觉认为的一样,拷贝对应内存。通过反汇编看编译器的行为,效果跟memcpy一样,还省掉了函数调用开销,代码更加的简洁明了。// @file: main.cstruct node { ...

2018-10-05 18:07:50 39753 3

原创 程序员工作后如何有效的学习

工作满三年了,做技术不能只顾埋头搬砖,也要定期回顾,思考未来,不要让自己成为那种一年经验用了十年的开发者。工作中积累的局限从自己的工作谈起,菊厂C/C++通信软件开发。工作三年来,第一年收获最多,编程方面技能基本补齐可以很好的应对业务需求的开发,问题的定位解决。但是,很多稍微深入一点的知识,都还是自己看书自学的,稍微深入点的学习都只能靠自己。观察周围同事,对技术很有热情的并不是很多,很多老...

2018-09-09 12:31:54 11638 9

原创 macOS使用VirtualBox安装Ubuntu18,配置共享目录和ssh

之前一直使用Parallels Desktop,今天想装一下最新的Ubuntu18,总是出问题。于是尝试了下VirtualBox5这款开源的虚拟机软件,挺好用,比之前Parallels Desktop占用的资源少了很多。配置共享目录点击菜单栏中的 Devices->Shared Folders->Shared Folders Settings… , 配一个Machine Fo...

2018-09-08 19:45:29 1074

原创 HTTP1.1 基础: 用C语言实现200行内的极简http server

对HTTP协议有了基础的了解后,可以看这篇: HTTP 基础: 请求和响应的消息交互细节, 就可以用纯C来实现一个极简的http server了。这个的http server主要完成此功能: 通过URL访问server根目录的html类型文件。代码如下:#include <sys/types.h>#include &

2018-09-02 23:38:55 6315 4

原创 HTTP1.1 基础: 请求和响应的消息交互细节

HTTP 基础概念都8102年了,即使不是一名web程序员,也还是需要了解一下http基本知识的。下面是RFC2616对HTTP的描述: The Hypertext Transfer Protocol (HTTP) is an application-level protocol for distributed, collaborative, hypermedia informatio...

2018-08-26 16:36:01 3416

原创 ML笔记 01:TensorFlow相关基本概念和基于符号的编程范式

最近学习机器学习相关的东西,理论看了一部分后,想跑几个TensorFlow的小例子,在实践中体会一下,发下总是不能够很好的理解TensorFlow的代码。然后各种查资料,看了下TensorFlow的入门知识,才了解到TensorFlow的编程范式是一种典型的基于符号的编程范式,计算过程是延迟计算,典型的惰性求值。TensorFlow的基本概念Tensor 张量Tensor是张量,Flo...

2018-08-12 18:27:08 766

原创 ML笔记 00:机器学习类型 & 深度学习和传统机器学习的区别

人工智能的核心是机器学习。机器学习是一门专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能的学科。机器学习分类监督学习监督学习是一个单次决策的过程。监督学习可分为回归(Regression)和分类(Classification)问题。在回归问题中,我们会预测一个连续值。也就是说我们试图将输入变量和输出用一个连续函数对应...

2018-07-31 00:09:31 4140

原创 Linux C/C++定时器的实现原理和使用方法

定时器的实现依赖的是CPU时钟中断,时钟中断的精度就决定定时器精度的极限。一个时钟中断源如何实现多个定时器呢?对于内核,简单来说就是用特定的数据结构管理众多的定时器,在时钟中断处理中判断哪些定时器超时,然后执行超时处理动作。用户空间程序不直接感知CPU时钟中断,感知内核的信号、IO事件、调度,间接依赖时钟中断。软件实现动态定时器常用数据结构有:时间轮、最小堆和红黑树。

2018-07-16 22:55:49 36472 4

原创 Linux IPC: UNIX Domain Socket 基本用法

当前Linux IPC最常用的方法就是UNIX Domain Socket和TCP Socket了。使用TCP Socket可以看:Linux Socket TCP通信基本用法。这两种IPC一个很大的区别就是:TCP使用IP + Port来标记进程;UNIX Domain Socket使用文件来标记进程;由于上面差异,在socket API标记地址的结构体也有所不同,Domain S...

2018-06-27 00:21:01 2495

原创 理论不扎实,编程不会有自己的想法

工作也要经常研读基础理论理论知识要反复研读,不同时期的重温会有不同的感悟和理解。理论不扎实,写的代码不会有灵魂,看问题会看不到本质,更不会对技术的演进提出自己思考与见解,只能随波逐流的跟随,终日耗费在无穷无尽的业务细节中,领略不到技术本身的魅力。前阵子,公司终端部门发布了GPU Turbo,引起了技术圈不小的讨论,我不是搞GPU的,很多不懂,只能看到网上各路大神洋洋洒洒的讨论见解,甚是敬佩...

2018-06-25 23:53:13 672

原创 Linux C/C++调试:快速找出GCC O2优化编译的汇编与C源码的对应关系

相信很多C/C++程序员都有过线上gdb调试程序的经历,没有或者剥离了调试信息,线上运行的也是GCC -O2编译优化后的release版本,这时就要求快速看懂汇编指令和对应C代码的对应关系。进而,找到自己需要gdb print出来内存信息,或者针对性的下断点或观察点等,这些调试一切的前提都是要求快速看懂反汇编指令和对应源代码的对应关系。一个函数的反汇编短则数百,长则近万行甚至更多,如何一下子找到其...

2018-06-21 23:35:02 2083

原创 Linux C/C++适配malloc申请按页对齐的内存,方便使用mprotect

之前的一篇文章: Linux C/C++内存越界定位: 利用mprotect使程序在crash在第一现场。里面没有用malloc来申请按页对齐的内存,其实也可以适配malloc,多申请2页,取中间按照页对齐的内存使用。使用malloc,可以使得进程的地址空间布局不会相对原来发生太大变化。代码如下:#include <stdio.h>#include <stdlib.h&am

2018-05-23 00:33:07 5379

原创 大型软件开发中的流程与规范

对于长生命周期的大型软件,流程和规范十分必要。IT行业作为一个快节奏的行业,不光技术革新快,人员的更替也是很快的,没有严格的规范和流程,几个大版本迭代下来,可能产品的代码就维护不下去了。估计很多大厂的小伙伴面对自己日常开发维护的的code base会产生这样一种错觉,这么庞大复杂,逻辑绕来绕去,时不时会有些巨型函数,还有些看的让人崩溃的if esle分支,各种自造的轮子,历史遗留天书代码,但是...

2018-05-01 19:47:54 5358

原创 Linux C/C++内存越界定位: 利用mprotect使程序在crash在第一现场

对于大型Linux C/C++程序,内存越界和野指针类问题往往比较难定位。有的由于内存被非法改写造成了业务功能问题,有的则直接导致了程序crash,而且还经常不是第一现场。针对这种问题,可以采取的解决方法有:利用valgrind工具来排查,会影响程序性能;使用Address Sanitizer工具排查;如果是固定的内存被破坏,可以利用gdb watch来抓取第一现场的调用栈;可以利用G...

2018-04-20 22:43:49 11948 1

原创 Linux C/C++ 使用GDB环境变量和控制语句进行自动化调试

调试Linux C/C++后台程序,常常会gdb attach到对应进程进行调试,然后各种断点,观察点,观察内存等。但是,有时候我们需要能在gdb中做一些基本逻辑操作,主动call一个函数,甚至循环call几次等,这时就可以用gdb的环境变量和一些基本的控制语句。一个例子如下:#include <stdlib.h>#include <stdio.h>int a...

2018-03-19 22:41:29 1393

原创 Linux C/C++ 把Git commit SHA1值编译到程序中来方便查看版本

今天使用 Visual Studio Code,点击关于Visual Studio Code会呈现版本的Git commit SHA1值,这个对于查看一个发布的程序对应的源码十分的方便和精确,可以在非常方便的直接checkout出来对应程序对应的源码版本。对于Linux C/C++程序,如果想做到这样的效果,把SHA1值放到构建的产品,也非常简单。有两种办法:如果程序对外发布包含有很多的...

2018-03-11 17:14:04 3281

原创 小练习 - 单链表冒泡排序,交换指针域

链表的排序,好的做法是交换指针域。链表节点的数据域可能比较大,交换数据域可能会涉及拷贝过多的内存,影响性能。链表是链式存储,无法随机访问(base_addr + offset), 所以比较适合的办法是用比较两两相邻节点的冒泡排序法。当然还有一个办法就是,把所有的链表地址存到一个数组里,排序后重新遍历设置所有指针域,这个就多了两次遍历,也可以。下面是交换指针域的一个单链表冒泡排序的例子:#inc...

2018-02-18 14:29:54 2520 2

原创 Linux C/C++ 用variadic macro可变参数宏封装带文件行号和时间的日志接口

在实际的项目中,一般日志接口可以打印出对应的时间、行号、函数名、模块名、级别等信息,可以用variadic macro可变参数进行简单的封装。一个例子:#include <stdio.h>#include <sys/time.h>#include <time.h>/* 日志开关, 关闭打印只把宏需改为0即可 */#define LOG_SWIT...

2018-02-12 22:49:10 708

原创 Linux C variadic可变参数:va_list 在x86和x64下的区别与实现原理

仔细研究了下va_list的实现原理。通过看对应的汇编代码实现和Intel ABI手册,发现:在x86平台下,va_list可变传参是通过栈来进行;在x64平台下,va_list可变传参是是默认的calling convention;这是Inter官方的Linux ABI文档,详细说明了可变参的底层实现,以及相关的使用约定。 The va_list type is an ar...

2018-02-11 23:41:14 1727 1

原创 Linux C/C++编译和使用so共享库

本文给出一个Linux C 编译和使用共享库so的一个小例子。如下: 文件 my_math.c // @file: my_math.c#include "my_math.h"int add(int a, int b){ return a + b;}// @file: my_math.hint add(int a, int b);文件 test.c/...

2018-01-22 00:02:39 3374

原创 Linux C/C++ 程序员毕业工作两年多来的感想

从2015年年中毕业到现在2017年年底,自己已经工作两年半了。总结一下自己工作两年多的感想。主要是三点:1. 学习的方法与态度2.技术与业务的平衡3. 技术之外的学习

2017-12-17 17:17:05 10835 3

原创 Linux 文件描述符解析

关键数据结构在现代操作系统抽象中,进程是资源管理的最小单位,线程是CPU调度的最小单位。Linux有着“一切皆文件”的说法,很大的原因就是文件描述符这个强大的抽象,为I/O操作提供了一个统一的数据结构和接口。内核维护的3个数据结构:进程级的文件描述符表(descriptor table),每个进程都有自己独立的文件描述符表,主要包含了是:控制标志(flags)和指向打开文件表象的指针。POSIX标

2017-08-14 00:31:17 612

原创 Linux C函数入参和返回值是结构体时的汇编分析

在C语言程序中,一般不会直接传一个结构体给一个函数,也不会让函数的返回值直接返回一个结构体,这样会拷贝过多影响效率。但是这样也是合法的,有时候也会使用,并且有时候效率也并不会变得太差。C函数传参:参数少或者传入的结构体小只借助寄存器即可,否则借助栈。C函数返回值:如果返回一个比较小的结构体,借助寄存器即可,否则依旧借助栈。按调用约定,当返回值是较大的结构体时,会在caller栈里产生一个临...

2017-08-13 13:45:12 3247

原创 Linux C函数调用栈帧结构

Linux C程序的反汇编,每个函数第一个指令都是push %rbp,即当caller者调callee时,指令callq <fun addr> callee返回后的下一个指令地址压入栈帧,然后push %rbp 保存 rbp寄存器,紧接着mov %rsp,%rbp 更新rbp 寄存器这样层层调用构成函数调用栈,每个栈帧开始就是存的上一个栈帧的rbp, 结尾就是调用callee后的下一个...

2017-04-25 23:06:23 2524

原创 AWK 常见基本用法

在Linux下进行一些简单的文本处理, 尤其是涉及数据基本过滤加工汇总的,awk 是十分方便的, 复杂的处理还是用python比较好。总结一下一些 awk 的常用技巧:按列条件过滤awk '{print $1, $3}' info.txt # 输出指定列awk '$2==1 && $5=="ERROR"' info.txt # 按条件过滤,$2、$5是内置变量,表指定的列,

2017-04-19 08:00:21 630

原创 规律的作息

作息是否规律对一个人的身体状态影响很大。前阵子看了哈佛幸福课,知道自制力是一个有限的资源,好的做法的就是一段时间集中养成一个好习惯,然后保持下来。自己也算培养两个了:(1)定期的锻炼;(2)晚上或多或少的学习点东西。下一个自己要集中培养的习惯就是规律断点作息。因为要上班,自己早晨起床的时间通常也是比较固定的,但是晚上睡觉却不是很规律了。经常时不时就睡的比较晚,而且大部分都不是因为工作原因,都是晚上自

2017-04-17 08:11:52 4342 1

原创 操作系统原理:动态内存分配

动态内存分配背后的机制深刻的体现了计算机科学中的这句名言: All problem in CS can be solved by another level of indirection. — Butler Lampson ...

2017-04-12 23:21:13 5772

原创 小练习 - 哈希表之分离链接法

小练习 - 哈希表之分离链接法哈希表十分常用,这里做个小练习,冲突解决使用分离链接发。从哈希表的C语言实现角度来看,Hash本质上做了这样一个映射:key -> hashtable[index] -> addr, 新插入一个数据时,key由数据本身决定,存储地址addr则是系统分配,key通过哈希函数可以算出索引,查找索引对应哈表项目得到地址。采用分离链接法,底层数据结构主要是数据和单链表。这里未考

2017-03-18 01:03:24 821

原创 小练习 - IP地址int与string相互转换C实现

有次用到了IP地址int与str的转换,不想用socket的库函数,发现网上很多实现都挺啰嗦的,自己实现了一个,记录下,大小端序可以根据实际使用进一步做转换。/* ip 字符串合法性由调用者保证 */unsigned int ip_str2int(const char* ip){ unsigned int re = 0; unsigned char tmp = 0; ...

2017-03-13 23:10:30 4430

原创 小练习 - 基于链表的栈和队列

随手练下基本的数据结构,基于链表实现一个动态大小的栈和队列,最基本简单的数据结构要注意各种边界场景。基于链表实现,频繁增删调用mallc会带来一定开销,实际使用要看情况来定。基于链表的栈typedef struct _node { int data; struct _node* next;}node;typedef struct _stack { node *top;

2017-03-10 00:13:41 457

原创 操作系统原理:进程地址空间

Linux进程虚拟存储先回忆一下ELF文件的组织结构,可以看这篇文章:Linux 链接与ELF文件。程序执行后进程地址空间布局则和操作系统密切相关。在将应用程序加载到内存空间执行时,操作系统负责代码段与数据段的加载,并在内存中为这些段分配空间。Linux的进程地址空间大致如下:Linux内核虚拟存储内核虚拟存储器包含了内核的代码和数据结构。内核虚拟存储器的一些区域被映射到所有进...

2017-03-07 00:17:39 3522

原创 操作系统原理:虚拟地址

The Memory Hierarchy存储系统是有层次的,从快到慢依次是:CPU寄存器、静态SRAM、动态DRAM、磁盘。如下图: 如 Inter Core i7 存储结构如下: i7的存储架构支持48-bit虚拟地址,52-bit物理地址. Page Size启动时可配置 4KB or 4MB, Linux使用4KB,4-level page table hierarchy。...

2017-02-23 00:54:27 3911

原创 从汇编角度看C++类的方法访问类成员的原理

C++编译后最终也是生成了机器码,不需要任何解释器或虚拟机来运行。相比C语言,C++有了类class大大的方便了代码结构的组织,使得构建大程序简便了很多。实例化一个类后,类的成员方法就可以访问这个类的成员了,那么从汇编角度看,到底是如何实现的呢?原理也十分简单,类所有成员本质上就是一个结构体,每个类的方法第一个入参就是把这个结构体的地址穿进去,类的方法就是这样实现了访问类的成员。

2017-02-08 22:58:41 2237 1

原创 操作系统原理:链接与ELF文件

ELF文件本文主要针对Linux系统。在x86架构下,Linux使用的是ELF(Executable and Linkable Format)目标文件格式。目标文件的三种格式:Relocatable object file. 可重定位目标文件包含二进制代码和数据,编译时可与其他可重定位目标文件合并组成可执行目标文件,如 .o,.a文件。Executable object file. 可...

2017-02-05 17:06:18 2724

原创 小练习 - 排序:冒泡、选择、快排

好久没手写过排序了,用C89标准的C重新练习下三种排序方法,快排的边界还是需要注意下。练习这些经典算法要在脑子里能够形象的想象出这些数据结构的表现与操作,这样才能理解深刻。// c89 标准#include <stdio.h>// [begin, end) 前闭后开,索引范围是[begin, end - 1]// 冒泡, 稳定排序void bubble_sort(int data[], int

2017-02-02 22:07:29 581

原创 Linux 同步机制:自旋锁

自旋锁的特点与适用场景Linux自旋锁spinlock同一时刻只能被一个可执行线程持有。当一个线程试图获取一个已经被持有的spin lock时,就会一直忙循环-选择-等待锁重新可用。忙等待免去了线程挂起再被唤醒的转换,省去了两次上下文切换的时间。因而spinlock适合下面的场景:SMP多核系统中,持有自旋锁的时间小于完成两次上下文切换的时间,这种场景使用spinlock效率会比较高。所以一般在用户

2017-01-17 23:29:38 1700

原创 Linux 同步机制:条件变量

条件变量的优势条件变量提供了一种线程间的通知机制,达到条件唤醒对应线程,配合互斥量,可以解决多线程中大多数的同步问题。需要信号量的解决问题的基本都可以用条件变量加互斥量解决。由于信号量使用起来容易出错,实际工程中用互斥量和条件变量的更多。互斥量可以保护共享数据的原子访问,但是无法很好的保证条件时序,单纯的配合sleep调用的忙等待会浪费CPU,也无法做到第一时间感知到条件ok。这里配合条件变量就可以

2017-01-13 00:15:34 1085

原创 Linux 同步机制:读写锁

读写锁 读共享写独占读写锁也叫 shared-exclusive 锁, 也是一种同步机制。读写锁有三种状态:读模式下加锁,写模式下加锁,不加锁。有如下的使用约定:不加锁或者读模式加锁状态时,任何线程都可以读模式枷锁,但是写模式加锁会被阻塞;不加锁状态时,才可以进行写模式加锁;读模式加锁状态时,有线程进行写加锁,读写锁会阻塞后面的读加锁,防止试图进行写加锁的线程由于得不到锁而长期阻塞;读模式共

2017-01-04 21:48:54 792

MATLAB遗传算法源码与工具箱实用介绍

MATLAB的遗传算法源代码,工具箱的使用,相关的实例

2013-07-29

空空如也

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

TA关注的人

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