自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Binder Q&A

binder mmap 的内存是每个进程独立的吗?会存在拷贝?是独立的(1MB - 8KB),用于接收数据。发送 BC_TRANSACTION/BC_REPLY 请求的时候拷贝buffer 和 offsets到目标进程的 mmap 内存区,只拷贝这一次。如果所有进程共享这部分内存,要 mmap 更大的用户内存空间满足同等吞吐量,而且非常不安全,因为任意进程都能读并猜测其他进程传输的数据。说是...

2019-01-13 20:03:45 261

原创 64位系统能使用多少内存

疑问我们知道32位win7一般只能使用4GB内存,原因是如果按照地址宽度是32bit(其实并不是)来算的话系统最多只能管理2322^{32}字节的内存(通过补丁的方式可以使32位win7突破4GB的限制,关键词:ReadyFor4GB,后面我会讲下对其实现原理的猜测)。那么照这么算,64位系统应该能使用2642^{64}字节的内存,也就是16EB(1EB = 1024PB, 1PB = 1024TB

2016-12-30 22:21:34 18807 3

原创 GUI为什么不设计为多线程

在我们这批新人转正评审的时候,我师父问了我的小伙伴一个问题:为什么一些更新界面的方法只能在主线程中调用?师父没有问我这个问题,让知其然但不知其所以然的我有种侥幸逃过一难的心情。我想如果回答那是因为Android GUI库是单线程消息机制的,更新界面的操作必须放到主线程中执行,那师父可能继续问为什么Android GUI要设计成单线程的,我就不知道了。为什么它非得设计为单线程的?多线程不是更好吗

2013-10-20 23:51:29 7339 6

原创 Android JNI(NDK)开发总结

早就知道Java有个jni可以调用本地化代码,一直没有动力去研究它,现在公司想通过在Android中调用本地化代码来申请较多的内存以突破Android对单个进程的内存限制,这确实是可行的:我的Nexus4内存2G,Android限制每个进程64M内存,而我用NDK写代码申请到了1,276,641,280字节。在学NDK开发的过程中遇到了各种问题,现在我将在解决问题过程中收集到的一些链接贴出来以助后

2013-07-29 22:29:03 3770

原创 VirtualBox装ghost XP

一直使用"免费"的VMware,总觉得良心不安, 特别是走向工作岗位后尊重版权的意识越来越强烈, 心里想着还是用正版或者开源的好,于是就看上了开源的VirtualBox。VirtualBox支持VMware的vmdk格式的虚拟硬盘, 我原来在VMware中用的Fedora 14虚拟机直接就在VirtualBox中跑起来了, 但是XP却不行,于是我打算重新装一个XP的虚拟机。 于是就开始了我

2013-06-10 23:37:33 18830 3

原创 被开源折腾

在公司实习的时候我成功地从“免费”的UltraEdit转向了开源的Notepad。一开始觉得Notepad没UltraEdit好用——没有十六进制编辑,得用一个HexEditor插件来实现,这插件还不是很好用。但用着用着发现Notepad其实也有不少亮点,比如:双击选中一个单词就会在全文中高亮该单词、搜索结果用一个列表全部展示出来、……渐渐地就喜欢上Notepad了。我觉得

2013-06-10 23:25:41 1385 1

原创 封装 WinSock C/S 通信

最近在做一个小东西的时候又用上了TCP通信,之前用VB做过,用java做过,用MFC的CSocket也做过,不敢说精通此道,但体会还是有的,这次打算用C++与WinSock来实现一个DLL,这样不论是MFC程序还是非MFC程序都能用上。一直在用别人造的轮子,我也来试着造个轮子出来。  想封装一下WinSock的一大原因就是WinSock的调用太繁琐了,对于TCP通信来说最重要的不就是IP地址和

2013-05-26 13:15:49 2784

原创 git 两个给力的应用场景

git 能给开发者带来不少便利,这里我就讲两个场景。revert  revert 是恢复的意思,用过 svn 的同学应该都对 svn 的 revert 操作赞不绝口:它能把未提交的修改一键丢弃。它的应用场景就是我在git版本管理的优点中提到的,我们在源码中添加一些自测代码如 printf、System.out.println来对新增加的功能进行正确性测试,测试正确了之后我们可以用 svn

2013-03-21 19:28:23 2094

原创 修改任意 commit

目前在公司实习,两周了, 很多东西要学,博客更新慢,敬请见谅!  上一篇博客中提到了未 push 的 commit 都可以修改, 这一篇就来演示一下。修改上次提交的 commit  git 直接提供了修改上次提交的 commit 的选项。继续 Hello-World 项目,上次 README 经过两次提交, 变成了这个样子:现在我想修改第

2013-03-17 19:59:04 2331

原创 commit 和 push 的临界点

估计很多使用 git 的同学把握不住什么时候应该 commit, 什么时候又应该把未提交的 commits 都 push 上去, 今天我就把我的理解说一说。  首先,有一条原则应该是要遵循的: 提交描述 = 提交的修改。  凡是违背这一原则的都构成欺诈:提交描述   这种情况是这次提交中 实际修改的内容比提交描述中介绍的要多, 难道你想添个后门?提交

2013-03-12 20:46:20 8242 2

原创 .gitignore

git 可以管理所有文件的变更, 但并不是所有文件都有意义。大部分二进制文件没有意义  比如说 VC 工程的 Debug 和 Release 文件夹下的文件, 或者 java 项目的 bin 文件夹中的 class 文件, 这些文件都是基于源代码生成的, 只要有源代码就能生成出来,所以版本管理的时候应该忽略它们。有些文本文件也没有意义  比如说 VC 工程中的 .plg 文

2013-03-07 21:17:34 29079 8

原创 git版本管理的主要操作

这一篇就来介绍版本管理的主要活动——开发过程中的 git 操作。各种操作都只给出一个简单的例子让大家熟悉怎么使用,至于经验之谈就留待后作了。  首先,演示一下怎么基于 github 进行协同开发。 其实就是要把各个开发者都加入到版本库的开发者列表中。为了演示,我申请了两个 github 账号,一个在本机 win7 中使用,一个在虚拟机 XP 中使用,这样来模拟两只程序猿的协同开发。我照

2013-02-27 19:17:31 4699

原创 安装git和创建版本库

安装 git  首先介绍一下 git 是怎么诞生的:2005 年,当时 linux 内核使用商业软件 BitKeeper 进行版本管理。Samba的作者Andrew Tridgell 试图尝试对 BitKeeper 反向工程, 以开发一个能与 BitKeeper 交互的开源工具, 因此激怒了 BitKeeper 的东家 BitMover, 要求收回对 Linux 社区免费使用 BitK

2013-02-24 14:24:15 6949 1

原创 git如何知晓文件差异

求两版本之间的差异是一个动态规划问题  git 能发现任何的改动,但它是怎么发现的呢?难道它监控了我们对文件的读写操作? git 才没这么鸡冻……它是通过比较新旧版本,掐指一算算出来的O(∩_∩)O。  首先假设我们只能通过以下3个操作将旧版本演化为新版本:copy —— 复制旧版本当前行到新版本insert —— 在新版本中添加一行delete —— 跳过旧版本当前行  那么

2013-02-12 11:39:16 4686 4

原创 git版本管理的优点

如果软件规模比较大、或者多人开发,应该进行版本管理以避免源码的混乱。  之前还没用过 git 的时候,我以为版本管理就是给自己的程序自动升级版本号的软件(从 2.6.39 自动升级到 2.6.40),以至于当我看了 git、svn、cvs 的简介后,一度因为它们没有提供这样的功能而耿耿于怀。  版本管理软件其实是修改管理软件,它把程序源代码的两个版本之间的差异当做砖垒起来,并为我们提供管理

2013-02-07 17:03:36 3266

转载 如何保证代码的高质量?

转自:http://blog.csdn.net/szu030606/article/details/8573346 代码的高质量是软件的灵魂,代码  =  数据结构  + 算法,  而高质量的代码  =  优良的变量、函数命名  +  优良的代码结构、代码层次结构   +  数据结构  + 算法。时时刻刻想这上面的四点,你的代码就会渐渐的上新台阶,老板不给你加工资还真的不行。

2013-02-06 22:17:31 1130

原创 用String分析固定格式的文本

上学期做一个任务:从 log文件 中提取出 java异常(Exception)的相关信息。 log文件的每一行都有固定的格式:包括 时间戳、信息类型、信息内容 等等。  一开始我想这是不是得用编译原理那套工具 lex、yacc 来做?当时做大作业的时候感觉它们真的是无比强大啊!但仔细一想,觉得没有必要:每行文本有多项数据,每项数据都识别为一个记号(token),太麻烦了!没有什么语法,

2013-02-03 12:38:07 1881

原创 直接能用的数据结构

本篇算是对集合类的总结。  常用的数据结构有:数组、链表、栈、队列、树、图。 这些数据结构都可以直接或间接地用 stl、util 中的集合类来表示:数据结构数组链表栈队列树图C++vectorlistlistlistlistlistjavaArrayListLinkedListLinkedLis

2013-01-24 16:46:57 953

原创 算法

前 3 篇先后介绍了 链表、数组、map集合,它们都是用来存储数据的,stl 和 util 还提供了很多基于这些集合类的算法:一 copy  首先介绍的这个算法好像根本就称不上是算法,不过它确实挺有用的:  假如我们有一组数据要存到一个集合类中,并假设这组数据在编码过程中经常需要改动,所以我们尽量要做到数据变动的时候不需要改动其他代码。我们可以先临时定义一个数组,列出这些数据,然后用一

2013-01-17 20:05:04 778

原创 map集合

map集合简介  stl 和 util 都提供了 map 集合,关于 map 集合,类似的概念有:散列表:《算法导论》中看到的,通过哈希函数将关键字映射到一个表(数组)中,检索速度很快。关联数组:《编程珠玑II》中看到的,普通数组是通过整型下标来索引的,而关联数组则可用字符串或其他类型来索引。  总之,map 集合是一个存储着多个 键——值 对的集合。  stl 中的 map

2013-01-15 20:46:57 843

原创 动态数组

动态数组也是一个常用的集合类,stl 中的 vector、util 中的 ArrayList 就是动态数组。一 ArrayList 添加操作的平均复杂度是 O(1)  ArrayList 中使用成员数组 Object[] elementData 存储数据,还有一个成员变量 int size 表示数组中存储的数据的个数,elementData[0..size-1] 存储着 size 个数据。

2013-01-14 19:54:01 1028

原创 链表

Warring: 本篇文章纯粹是为了勾引你去使用 stl 或 java 集合类,未必面面俱到,在文末我会推荐一些其他链接。  大三以前我一直没写过什么大程序,一个程序顶多两三百行了事,总是不停地重造车轮:每个程序都重写一遍链表、栈、队列,认为这是依赖最少的“纯C程序”。  后来《数据挖掘》第一次上机作业——挖频繁项集,我又开始写“纯C程序”了:一开始就轻松地实现了一个链表,然后我发现还得实

2013-01-13 20:41:29 1624

原创 汇编实现的动态栈

汇编实现的动态栈   这一篇就是实现 d_printf,废话不多说,直接上代码。由于 VC 的内联汇编还是比较清晰,那就先贴 VC 版的。一、d_printf VC版#include void d_printf(const char *fmt, int n, int a[]){ static int size1, size2; static const char

2013-01-01 17:23:49 1480 4

原创 内联汇编

内联汇编   内联汇编是指在 C/C++ 代码中嵌入的汇编代码,与全部是汇编的汇编源文件不同,它们被嵌入到 C/C++ 的大环境中。一、gcc 内联汇编  gcc 内联汇编的格式如下:asm ( 汇编语句 : 输出操作数 // 非必需 : 输入操作数 // 非必需 : 其他被污染的寄存器 // 非必需 );  我们通过一个简单的例

2013-01-01 17:23:41 20103 3

原创 C语言的栈是静态的

C语言的栈是静态的   C语言有了可变参数之后,我们可以传任意个数的参数了,似乎挺动态的了,但是可变参数函数还是不够动态。一、鞭长莫及  我们可以在 main 中写出好几条参数个数不同的调用 sum 的语句,但是具体到某一条语句,sum 的参数个数是一定的,比如上一篇中的 sum(2, 3, 4) 的参数个数是 3。如果程序运行中调用 sum 函数的时候,参数个数根据用户输入而定,那就

2013-01-01 17:23:31 938

原创 可变参数

可变参数    C语言的可变参数的实现非常巧妙:大师只用了 3 个宏就解决了这个难题。一、可变参数的应用  这里实现一个简单的可变参数函数 sum:它将个数不定的多个整型参数求和后返回,其第 1 个参数指明了要相加的数的个数(va.c):#include #include // 要相加的整数的个数为 nint sum(int n, ...){ va_list ap

2013-01-01 17:23:17 754

原创 函数指针

函数指针 一、函数指针的值  函数指针跟普通指针一样,存的也是一个内存地址,只是这个地址是一个函数的起始地址,下面这个程序打印出一个函数指针的值(func1.c):#include typedef int (*Func)(int);int Double(int a){ return (a + a);}int main(){ Func p = Doubl

2013-01-01 17:23:03 830

原创 变量名、函数名

变量名、函数名   C程序在执行的时候直接用内存地址去定位变量、函数,而不是根据名字去搜索,所以C程序执行的速度比脚本语言要快不少。  对于函数中的局部变量来说,编译为汇编的时候,名字就已经被彻彻底底地忘记了,因为局部变量在函数帧中,这一帧要占多少字节,各局部变量在帧中的相对位置,都在编译成汇编的时候就可以确定下来,生成目标文件、可执行文件的时候也不需要再更改。  而 全局变量、sta

2013-01-01 17:22:49 1714

原创 static变量 及 作用域控制

static变量 及 作用域控制 一、static变量  static变量放在函数中,就只有这个函数能访问它;放在函数外就只有这个文件能访问它。 下面我们看看两个函数中重名的static变量是怎么区别开来的(static.c):#include void func1(){ static int n = 1; n++;}void func2(){ s

2012-12-31 16:41:45 7084 1

原创 编译优化

编译优化   C语言没有汇编快,因为C语言要由编译器翻译为汇编,编译器毕竟是人造的,翻译出来的汇编源代码总有那么N条指令在更智能、更有创造性的我们看来是多余的。  C语言翻译后的汇编有如下恶劣行径:C语言偏爱内存。我们写的汇编一般偏爱寄存器,寄存器比内存要快很多倍。当然,寄存器的数量屈指可数,数据多了的话也必须用内存。内存多余读。假如在一个 for 循环中经常要执行 ++i 操

2012-12-31 16:41:33 2484

原创 进程内存分布

进程内存分布   之前一直在分析栈,栈这个东西的作用也介绍得差不多了,但是栈在哪儿还没有搞清楚,以及堆、代码、全局变量它们在哪儿,这都牵涉到进程的内存分布。linux 0.01 的进程内存分布  内存分布随着操作系统的更新换代,越来越科学合理,也越来越复杂,所以我们还是先了解一下早期操作系统的典型 linux 0.01 的进程的内存分布:  linux 0.01 的一个进程固定拥有

2012-12-31 16:41:18 4929 3

原创 未初始化全局变量

未初始化全局变量   为下一篇介绍进程内存分布做准备,这一篇先来介绍一下未初始化全局变量:  未初始化全局变量,这名字就很直白,就是 C 程序中定义成全局作用域而又没有初始化的变量,我们知道这种变量在程序运行后是被自动初始化为 全0 的。编译器编译的时候会将这类变量收集起来集中放置到 .bss 段中,这个段只记录了段长,没有实际上的内容(全是0,没必要存储),在程序被装载时操作系统会为它分

2012-12-31 16:40:50 15402 6

原创 所有递归都可以变循环

所有递归都可以变循环   这是函数帧的应用之二。  还记得大一的C程序设计课上讲到汉诺塔的时候老师说: 所有递归都可以用循环实现。这听起来好像可行,然后我就开始想怎么用循环来解决汉诺塔问题,我大概想了一个星期,最后终于选择了……放弃…… 当然,我不是来推翻标题的,随着学习的深入,以及"自觉修炼",现在我可以肯定地告诉大家:所有递归都可以用循环实现,更确切地说:所有递归都可以用循环+栈实现

2012-12-30 16:54:04 11413 5

原创 谁调用了main?

谁调用了main?   这是函数帧的应用之一。操作可行性  从上一篇中可以发现:用帧指针 ebp 可以回溯到所有的函数帧,那么 main 函数帧之上的函数帧自然也是可以的;而帧中 旧ebp 的上一个四字节存的是函数的返回地址,由这个地址我们可以判断出谁调用了这个函数。准备活动  下面就是这次黑客行动的主角(up.c):#include int main(){

2012-12-30 16:53:43 1664

原创 函数帧

函数帧   这标题一念出来我立刻想到了一个名人:白素贞……当然,此女与本文无关,下面进入正题:其实程序运行就好比一帧一帧地放电影,每一帧是一次函数调用,电影放完了,我们就看到结局了。  我们用一个递归求解阶乘的程序来看看这个放映过程(fac.c):#include int fac(int n){ if(n <= 1) return 1; ret

2012-12-30 16:52:46 2284

原创 内存对齐

内存对齐 为什么要进行内存对齐  在计算机组成原理中我们学到:一块内存芯片一般只提供 8 位数据线,要进行 16 位数据的读写可采用奇偶分体来组织管理多个芯片, 32 位也类似:  这样,连续的四个字节会分布在不同的芯片上,送入地址 0,我们可将第 0、1、2、3 四个字节一次性读出组成一个 32 位数,送入地址 4(每个芯片接收到的地址是1),可一次性读出 4、5、6、7 四个字

2012-12-30 16:47:29 2091

原创 奇怪的宏

奇怪的宏   这一篇介绍这些奇怪的宏:一、do while(0)  为了交换两个整型变量的值,前面值传递中已经用包含指针参数的 swap 函数做到了,这次用宏来实现(swap.c):#include #define SWAP(a,b) \ do{ \ int t = a; \ a =

2012-12-29 16:21:04 611

原创 结构体

结构体   结构体是 C 语言主要的自定义类型方案,这篇就来认识一下结构体。一、结构体的形态  C源程序(struct.c):#include typedef struct{ unsigned short int a; unsigned short int b;}Data;int main(){ Data c, d; c.a = 1;

2012-12-29 16:20:46 656

原创 字符串

字符串   这一篇分析字符串,字符串经常被使用,但是它的秘密也不少:一、字符串的存储位置  C源程序(string1.c):#include int main(){ puts("Hello, World!"); return 0;}  我们直接看可执行文件的反汇编结果:[lqy@localhost temp]$ gcc -o string1 stri

2012-12-29 16:19:56 820

原创 数组和指针

数组和指针   指针和数组有什么区别?  C程序(array.c):#include int main(){ int date[3] = {2012,11,11}; int *p = date; int a = date[1]; int b = p[1]; printf("a:%d b:%d\n", a, b); printf

2012-12-29 16:19:04 516

空空如也

空空如也

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

TA关注的人

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