- 博客(44)
- 收藏
- 关注
原创 linux wireless tools
http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html
2013-11-18 14:04:17
435
原创 每日阅读12内核设计与实现——中断处理程序与中断上下文
中断处理程序是不会重入的,当中断发生时,所有处理器上同一中断线上的其它中断被禁止,绝不会出现同一中断线的嵌套中断。。。而其它中断线则是打开的,能被处理的。。这些准则,极大的简化了中断处理程序的编写。。当内核接受到一个中断后,将依次调用在该中断线上注册的每一个处理程序(从这一点看,一个中断可能会有很多中断处理程序要执行。。)每一个处理程序必须知道它是否与这一中断相关,因此它要
2013-04-11 20:10:56
592
原创 每日编程28之求最大子数组(o(N)复杂度)
之前研究算法,还剩下三大难题——KMP,rb-tree和DP。。本来是想把DP这一遗留问题解决,就看到了这个问题,后面才发现这个问题其实很简单,完全用不到动态规划的思想,或者是最简单的一维DP。问题描述,一个数组,n个元素,有正有负求最大子数组,要求o(N)复杂度例如,输入数组为 1,-2,3,10,-4,7,2,-5 则和最大的子数组为3,10,-4,7,2
2013-04-11 13:29:15
853
原创 每日编程27之linux系统调用——进程管理
进程ID的唯一性,多数UNIX系统采用的延迟重用(防止新进程的ID被认为是已经被删除进程的ID)策略。。。系统中存在一些专用进程:(1)ID为0的进程通常是调度进程(交换进程)swap,它不执行任何磁盘程序,因此被称为系统进程(2)ID为1的进程为init进程,在系统启动结束时由内核调用,程序文件为/etc/init 或/sbin/init...该进程负责启动一个unix系统,通常
2013-04-10 21:28:58
504
原创 每日阅读11之内核设计与实现——注册中断处理程序
好久没有写博客了,已经有点迷失自我,忘了自己最重要的事情,罪过罪过。。。中断处理程序是管理硬件的驱动程序的组成部分。每一设备都有相关的驱动程序,如果设备使用中断的方式与CPU通信,那么驱动程序就会注册一个中断处理程序.(1个?)驱动程序通过函数request_irq()注册一个中断处理程序,并激活相应的中断线(?什么东东,从下文看来像是多个中断处理程序共用的一个中断号)。。。定
2013-04-10 20:10:59
612
原创 每日阅读9之linux内核设计与实现——中断上半部与下半部
中断处理(1)要求速度快(2)完成的工作量多这是不可能的,因此引入中断处理上下半部的概念。。接受到一个中断,立即开始处理有严格时限的操作(如从硬件接受数据并存储,答复硬件),另外一些工作被允许稍后执行,在合适的时机开始中断下半部的处理。。linux提供了实现下半部的各种机制。。以网卡中断为例,当网卡接收到数据包后,产生中断,内核开始从网卡缓冲区中
2013-03-29 19:35:44
412
原创 每日月的8之linux内核设计与实现——中断与中断处理
计算机中CPU需要与外围设备硬件进行通信,而二者之间的速度差距使得让CPU等待外围设备处理完成这绝不是个好办法。。所以,在外围设备处理数据期间,CPU去执行其他任务。。但是,当外围设备处理完数据后,CPU怎么知道呢?一种办法是CPU周期性的轮询,这太浪费CPU时间。。所以,引入了中断机制,硬件在需要的时候想内核(确定是内核,不是CPU,这种机制应该是软件层面的。。。,错了,其实还是CP
2013-03-28 14:18:57
645
原创 每日阅读7之linux内核设计与实现——实时调度与调度系统调用
linux普通的进程调度策略是SCHED_NORMAL,实现在CFS调度器类中linux 提供二种实时调度策略SCHED_RR,SCHED_FIFO,实现在linux实时调度器中,实现在kernel/sched_rt.c中。。SCHED_FIFI为优先级抢占的实时调度策略,一旦较高优先级的进程获得资源,便会一直占用,值得阻塞或自己显示的放弃处理器资源。SCHED_RR为待时间片的SCH
2013-03-28 13:45:45
610
原创 每日阅读6之linux内核设计与实现——抢占与上下文切换
上下文切换,即由一个可执行进程切换到另一个可执行线程。由kernel/sched.c中的context_switch()函数完成,当一个进程准备投入运行时,schedule()调用该函数实现进程切换。该函数完成二项基本工作(1)调用中定义的switch_mm(),负责将虚拟内存从上一个进程映射切换到新进程中去。(2)调用声明在中的switch_to(),负责将上一个进程的处理器状态
2013-03-25 20:46:21
491
原创 每日阅读5之linux内核设计与实现——linux内核调度之睡眠与唤醒
进程休眠(被阻塞)的原因有很多种,但都是在等待某一种事件(1)文件I/O磁盘读取,键盘输入等硬件事件(2)获取一个已经被占用的内核信号量等。。。操作休眠:进程把自己标记成休眠状态,从可运行红黑树中移出,加入等待队列,调用schedule()选择和执行一个其他进程唤醒:进程被设为可执行状态,从等待队列中移到可执行红黑树休眠的进程可能出于二种状态,但位于同一等待
2013-03-24 16:29:19
505
原创 一些有待解决的技术问题
红黑树的具体实现模式匹配:自动机方法,KM P设计一种语言,并实现其编译器写一个操作系统写一个web服务器分析一些框架/平台的源代码,如hadoop,openstack
2013-03-24 12:24:18
594
原创 每日阅读4之linux内核设计与实现——linux调度实现之调度器入口
linux调度的入口函数时schedule(),定义在文件kernel/sched.c是内核其它部分用于调用进程调度器的入口:选择哪个进程可以运行,何时将其投入运行通常需要和一个具体的调度类相关联,一般是优先级最高的,每个调度类都有一个自己的可运行队列这个函数唯一的作用就是调用pick_next_task,依次检查每个调度器类,并且从最高优先级的调度器类中选择最高优先级的进程运行。。
2013-03-23 16:52:56
577
原创 每日阅读3之内核设计与实现(第三版)4.5——linux调度实现之进程选择
在引入CFS调度思想的同时,我们希望能实现完美多任务处理器,以保证每个进程有相同的虚拟运行时间。但现实中并不存在这样的多任务处理器,CFS使用一个很简单的规则来均衡所有进程的虚拟运行时间,即每次选择当前vruntime值最小的进程去执行。。为实现这一点,CFS使用红黑树rbtree来组织可运行进程队列,所以实际上对于可运行进程调度的相关操作,实际上就是红黑树数据结构的一些基本操作的变形。。
2013-03-19 09:38:04
571
原创 每日阅读2之linux内核设计与实现11.7.1定时器的使用
定时器(动态定时器,内核定时器)是管理内核时间流逝的基础。内核经常需要推后执行某些代码(所谓的下半部机制),因此需要一种机制,使工作在指定的时间点完成,这就是内核定时器的作用与目标。。、使用原理: 初始化一个定时器,设置超时时间,指定超时发生后的处理函数,激活定时器。。定时器并不周期性运行,超时后自动撤销(动态)。。。定时器在内核中应用非常普遍。。定时器结构timer_list,定义在
2013-03-19 09:36:08
689
原创 每日编程25之求二叉树镜像
思路很简单:对二叉树进行先序遍历,如果树根节点的左右子树同时为空,则返回;若不同时为空,则交换左右子树(即交换root->left,root->right)。。。。so easy。。。
2013-03-19 08:58:19
744
原创 每日阅读1之内核设计与实现(第三版)4.5——linux调度实现之时间记账
前面讨论CFS调度算法的动机和内在逻辑,下面开始探索CFS是如何实现的。相关代码位于kernel/sched_fair.c文件中。主要包含四个组成部分:(1)时间记账(2)进程选择(3)调度器入口(4)睡眠与唤醒今天,主要关注时间记账这个部分。。。所有的调度器都必须对进程的运行时间进行记账,大多数unix系统采用为进程分配一个时间片,每当系统时钟节拍发生时,时间片减
2013-03-18 11:20:07
926
原创 每日编程24之BST
BST,二叉查找树,又叫排序二叉树,指一种树,对于每一个树节点,其左子树的值关键的操作(1)根据元素序列,初始化,构建一颗二叉查找树,基于插入操作(2)对于一颗二叉查找树,插入一个元素,并保持二叉查找树的特征(3)查找操作,删除操作int insert_bst(BTree bst,int e){ struct node *pt = bst;
2013-03-18 10:03:02
678
1
原创 每日编程22之递归实现栈的反转
这个问题还是蛮复杂的,主要的解题思想是汉诺塔和九连环问题。。要求空间复杂度O(1)既然是反转栈,那么首先所有的栈元素都应该先出栈,那么如何存储这O(n)的元素?既然是递归的方法,很容易想到用递归函数栈来存储。。关键是如何实现反转?这样一次递归出栈是无法解决问题的,等等,这怎么看怎么像"汉诺塔问题",好吧,我们先去研究一下它吧。看到的实现代码,递归逻辑如上图所
2013-03-17 20:15:30
1059
原创 每日编程23之汉诺塔问题
问题的描述是,输入n个盘子,从从小到大排列在一起,设为A另有B,C二个托盘如何移动,将A中的n个托盘移动到C中,同时在任何时候保证大的盘子在小的盘子下面普遍的通用的递归算法如下int hanoi(int n,char A,char B,char C){ if(n==1) { printf("m
2013-03-17 13:05:39
411
原创 一些高层的资源
大神博客(1)http://wangcong.org/blog/名校资源(1)斯坦福计算机系统实验室 http://csl.stanford.edu/、(2)MIT EE&&CS学院 http://www.eecs.mit.edu/(3)CMU CS学院 http://www.cs.cmu.edu/\(4)UC berkeley CS学院 http://www.
2013-03-16 19:13:19
464
原创 每日编程21之单链表相交,环的相关问题研究
首先如何判断二个单链表是否相交,也就是所谓的Y型链表问题。算法很简单,只要分别遍历二个链表,对比二个链表的表尾元素是否相同即可那么再进一步,如何找到这二个链表的交汇点。只要在遍历的时候,记录2个链表的长度,M,N,假设M>N则长度为M的链表先走M-N步,然后二个指针同时走,当二个指针第一次相同的地方就是链表的交汇点。判断一个单链表是否有环,如果有环的话,如何找到起始
2013-03-16 12:40:30
525
原创 每日编程20之树中二个节点的最近父节点
输入是一棵树中的二个节点指针(有可能是同一个指针)输出应该是指向这二个节点最近父节点的指针。考虑采用递归的思想去做,后序遍历二叉树遍历0号节点,遍历1号节点,遍历4号节点,发现其为first,继续遍历5号节点,遍历2号节点,发现其为second,此时二个节点都已经遍历到了,不需要对从根节点开始的每个节点后续遍历,若某一个节点的(左右)子树同时包含first,seco
2013-03-16 10:07:29
596
原创 每日编程20之用一个数组实现2个和3个栈
用一个数组实现2个栈很简单,只要一个栈栈底在数组左边,向右生长,另一个栈栈底在数组右边,向左生长。判断栈满的条件是二个栈元素之和超过数组大小。实现3个栈似乎有难度。。。直观的想法是,将数组静态的分为3个区域以实施3个栈,这样的话,存储空间的使用会非常的不灵活。对这个想法的一个优化是,3个栈的栈底分别是数组的start,mid,end 。。mid这个栈的push,pop操作交替左
2013-03-14 20:05:19
482
原创 每日编程19之二个精妙小算法
(1)求单链表的倒数第四个元素第一种最直观的想法是,用二个指针first,second;初始时second比first多三步,当second走到结尾时,first的位置就是倒数第四个元素这个算法的优点是思想直观,容易实现。但需要考虑链表元素个数少于4个节点的没种情况。。第二种较为新颖的算法是,用一个数组arr[4]作为辅助存储,初始时arr中每个元素是一个特别的值,比如-1.01(最好
2013-03-13 09:06:09
733
原创 每日编程18之中位数/任意第K大的元素
中位数(中指)是指一串元素序列中值处于中间的那个元素。求中位数最直观的一种想法是,先将数据排个序,然后取中间元素,平均复杂度为O(nlogn)。另一种巧妙的想法是利用快速排序的划分步骤,每次将元素序列划分二份,中位数必然存在于其中的一个子序列,这样每次划分都可以抛去部分序列。这种算法的时间复杂度为O(n)递归函数,求解(p,q)序列中的第k个元素,,...int midVa
2013-03-12 13:26:31
428
原创 每日编程17之字符串匹配朴素算法
字符串匹配朴素算法的核心思想是:从待匹配字符串的首字符开始依次和模式串匹配,若匹配成功则返回位置,若匹配不成功则接着匹配下一个字符开始的串。。直到,待匹配串余下的长度小于模式串。。。所以这里要频繁的调用了求字符串长度的函数,但如果每个字符都开始求长度,整体复杂度就不是O(mn)了,而是O(n2)。。。其实也不用这样,初始的时候求一下长度,就可以了。。。int str
2013-03-11 10:20:27
413
原创 每日编程16之判断数是否为平衡二叉树
平衡二叉树的定义是,对于树中的任一节点,其左右子树高度差不超过1(即只可以为-1,0,1三种情况)这里的树的高度是指从叶子节点(高度为0)算起的左右子树最高的值+1。这里也有递归的逻辑。判断一颗树(树的唯一标志/入口是其root节点)是否平衡,就是比较其左右子树的高度差是否小于1.。现在的解决方案是,递归思想+树的后续遍历递归需要对每一个节点都进行处理,对于一般
2013-03-10 10:54:44
558
原创 每日编程15之用二个队列实现栈数据结构
看到这个问题,我现在的想到的解决方案是:二个队列中,始终有一个队列(队列1)为空,另一个队列(队列2)为栈中的元素,入栈的操作就直接将元素放入队列2(所以栈满的条件就是队列2满),出栈时将队列2的元素依次出队并向队列1入队,直到队列2的最后一个元素,也就是栈顶的元素出栈。。。。此时队列1和队列2的次序和作用发生了一个翻转。。。。要处理的细节情况还是比较多比如push的时候,要处
2013-03-09 11:15:58
493
原创 每日编程14之取单链表中间元素
我的直观想法是遍历单链表,统计元素个数,然后确定中间元素的位置,在此进行遍历。。。看到的比较精妙的算法是,用二个指针first,second分别走一步,二步。。当second走到队尾/接近的时候,first应该就是中间/接近中间元素的位置这里的关键是,处理"接近"这个模糊的概念。。。来二个图,直观的展示一下..首先是元素个数分别为偶数/奇数个的情况所以每次都要判断sec
2013-03-08 10:44:18
625
原创 每日编程13之希尔排序
核心思想是,分组插入排序,减小组间元素的距离,当距离为1时排序完成;写程序的要点还是循环控制首先,距离变量gap,初始为4依次减半2,1.对于gap=4的情况,就有四个分组(0,0+gap,...),(1,1+gap,...)(2,2+gap,...),(3,3+gap,...)即每个分组初始分别为0~gap-1对于gap=2的情况在每个分组的元素序列确
2013-03-07 15:42:47
362
原创 每日编程12之用二个栈实现队列操作
用二个栈实现一个队列现在的基本想法是:2个栈inS,outS一个栈用来取出队首元素,另一个栈用来加入队尾元素入队操作:即将元素压入栈inS,若inS栈满,则检查outS是否为空,若是则主动将inS中的元素pop并push到inS中去,否则则显示队列满出队操作:从栈outS取出元素,若栈空,将栈inS中的元素全部pop并push到outS中去,若二个栈都空,则说明队列为空算法
2013-03-06 13:39:39
422
原创 每日编程11之树的层次遍历
核心思想,是用队列作为辅助数据结构实现。队列的初始化,入队,出队的操作是关键初始时:将root指针入队(root != NULL,否则直接返回)每次从队列里取出队头元素,打印,并将其左右子树(若不为NULL)入队若队列为空,则遍历结束队列数据结构:队列空和队列满的判断这是在牺牲一个元素的存储空间下,队列空和队列满的
2013-03-05 22:16:37
484
原创 每日编程10之二叉树的先序遍历的非递归版本
这是用栈模拟的一个过程,要注意的地方是:(1)入栈的顺序是先右子树,后左子树,这是才能保证出栈是先左后右初始化时:若根节点不为NULL,将根节点入栈,否则return;核心处理操作:打印数节点元素值循环结束条件:栈为空核心代码:int TreePrint_preorder_nonRecur(BTree root){ if(!root
2013-03-03 15:41:41
176
原创 每日编程9之二叉树的先序遍历递归版本
本文研究先序遍历的方式建立二叉树,打印二叉树(递归方式)首先是,先序遍历建立二叉树。输入:014xx5xx2x6xx(1)接受输入元素element,建立一个新的节点,若该节点为第一个节点,则将树root指针指向它(这个也不需要,只要递归开始的时候,将root传进去,root会改变指向,root->left也会)(2)递归处理左右子树,结束递归的条件是输入为
2013-03-02 12:55:45
281
原创 每日编程8之创建一个栈并使之min,push,pop复杂度均为O(1)
直观上push,pop的复杂度肯定是O(1)..当然,这里的min操作应该是找出栈中的最小元素,但并不要求将该元素出栈。。。核心思想是,栈顶元素同时记录着当前栈的最小元素指针这里涉及到需要证明的一个地方,这也是算法正确性的体现,即无论是出栈还是入栈,这样的栈结构设计都能够保证始终通过栈顶能直接找到最小元素结构体竟然可以直接assignment,太神奇了,s1
2013-03-01 18:19:57
296
原创 每日编程7之快速排序非递归版本
递归算法转化为非递归实现的核心思想是"用栈来模式递归函数栈"。实现主要考虑:入栈/出栈的逻辑对于快速排序来说。。栈元素包括,输入序列的左右下标,初始时将0,n-1每次循环 取出栈顶元素(p,q),若q 在该段元素序列中执行快速排序核心算法: 确定新的中间元素 i+1 将(p,
2013-02-28 17:51:06
270
原创 每日编程6之单链表反转递归版本
既然链表逆序输出可以用递归方法实现,单链表反转也可以采用递归思想实现。不同的地方时,后者需要破坏原有的链表结构不晓得采用1个指针能不能实现先考虑用2个指针p,q分别记录原来的链表关系初始时:p = NULL,q = head; 特殊条件为q==NULL,表示链表中没有元素,这也可以作为递归结束条件(这可以成为一种找递归结束条件的思路)递归处理操作是:p=q;q=q->
2013-02-27 11:01:00
299
原创 每日编程5之逆序输出单链表
因为只要求逆序输出,考虑采用递归思想,以减少对链表结构的破坏。这里主要训练递归算法的编码技巧。首先,这里递归的单位应该是每个链表元素,对这个元素的核心处理操作是打印其数据项,因为是倒序输出,所以将递归处理操作放在核心处理操作之前。递归结束的条件是,当前节点为空节点,这个时候不做任何处理,前面的递归函数开始依次出栈,因为第一个出栈的是链表尾元素,所以后续的数据输出也是逆序的。核心代码
2013-02-26 09:44:20
274
原创 每日编程4之单链表反转
这好像是marvell笔试的一道题!这里的链表是无头单链表,输入应该是单链表的表头元素指针head,输出是反转后的表头元素指针存三种情况:(1)若head == NULL ,即链表中没有元素,返回head(2)若p=head q=p->next为NULL 即只有一个元素,则返回p(3)若链表中有2个或2个以上的元素,初步想了一下,这几种情况应该可以统一起来...可以
2013-02-26 09:16:40
237
原创 每日编程3之快速排序随机化版本
前文所述,快速排序的平均时间复杂度与输入元素序列的均衡化程度相关,在最坏情况下,每次选择的pivot元素都是最大元素/最小元素,时间复杂度为n*n 像1 2 3 4 5 6这种若输入元素较为均衡,平均时间复杂度将为logn*n所以对快速排序的输入序列做一个随机化预处理,可以有效降低排序的时间复杂度,在实际编程中,可以采用每次随机选择A[p-q]中的一个元素作为piv
2013-02-24 10:18:41
276
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人