博文

ROM and RAM

RAM Random Access Memory or RAM is a form of data storage that can be accessed randomly at any time, in any order and from any physical location., allowing quick access and manipulation. RAM allows the computer to read data quickly to run applications. It allows reading and writing. It is non-volatile i.e. its contents are retained even when the device is powered off. Static RAM vs. Dynamic RAM Static RAM has a pair of transistors forcing each other on and off, so there are electric fields turning on channels to conduct and turn off the opposite transistor. This is a self-reinforcing state, so  it can go on forever. In a dynamic RAM there is just a little bit of charge or not on the gate of a transistor.  This charge will leak away in milliseconds, as there is nothing actively maintaining it all the time.   So dynamic RAM need to have a refresh jolt every few milliseconds , where a pulse causes the read transistor to reinforce the charge level on its gate. Dyna...

保护眼睛的颜色设置

第一步, 在桌面上点击鼠标右键,依次点击“属性”、“外观”、“高级”按钮。   第二步, 在打开的“高级”对话框中,在“项目”下拉列表里选择“窗口”。   第三步, 再打开右边对应的“颜色”列表,选择其中的“其他”一项。在打开的对话框里, 把“色调”的参数设置为85,把“饱和度”参数设置为90,把“亮度”参数设置为205。点击“添加到自定义颜色”按钮,再点击“确定”退出设置。   第四步(如果在看那些很刺眼的网页的情况下),打开IE浏览器,选择“工具”栏中的“internet选项”,点击“辅助功能”按钮,在“不使用网页中指定的颜色”前打钩。然后次点“确定”。

Floyd的cycle-detection算法解析(原创)

图片
要解决的问题是: 如何确定一个链表中时候存在环,如果存在的话,环的起点在哪里? 借用这张经典的解析图 Floyd 的算法又叫做龟兔赛跑算法,那么我们就用龟兔赛跑来解释。 我们假设乌龟和兔子的速度是1:2,然后 假设乌龟的兔子在赛道的某一点相遇了 。(相当于他们直线跑入一个环形赛道,然后在赛道的某一点相遇了)那么因为他们跑得时间是一样的,即他们跑得路程1个是i,另一个是2i。借用上图的表示,我们有如下等式: 1) i = m + p*n + k 2) 2i = m + q*n + k 这里的p和q分别是兔子和乌龟在环里跑得圈数。q>p 解上面的等式去掉i,我们就得到下面这个重要的等式: m + k = (q-2p) * n  (等式一) 因此,如果我们能够证明至少有一种k, p, q的值可以使得这个等式成立,我们就证明了这样的m和n的是存在的。 (如果环存在,即上面等式成立,m和n的值是确定不可变的,只有k,p,q是可变值。) 进而也就证明了乌龟和兔子的相遇是成立的。 这里我们只要使 k = m*n-m; q-2p = 2m; 也就是说存在k,q,p的确定的值的组合(因为他们都可以用m和n表示),使得上式成立。 下面我们来解决第二个问题,即环的起点在哪里。 让我们再加一只乌龟进来,叫做乌龟二号。 乌龟二号和乌龟一号有同样的速度。当乌龟二号在链表起点时,乌龟一号和兔子相遇在环内的K处。 现在,当两只乌龟一起走m步时,即乌龟二号到达了环的起点,这时候 乌龟一号走的总路程 = m + p*n + k + m 根据等式一计算m+k得出: 乌龟一号走的总路程 = (q-2p) * n + p*n + m 即 乌龟一号走的总路程 = (q-p)*n + m 所以当乌龟二号在环起点的时候,乌龟一号走过了(q-n)圈个环,再加上m的路。所以乌龟一和乌龟二第一次相遇的时候的点就是环的起点。 参考 http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare

Linux汇编语言开发初探(2)

上述输出信息的第一列是指令对应的地址码,利用它可以设置在程序执行时的断点: ald> break 0x08048088 Breakpoint 1 set for 0x08048088     断点设置好后,使用 run 命令开始执行程序。ALD 在遇到断点时将自动暂停程序的运行,同时会显示所有寄存器的当前值: ald> run Starting program: hello Breakpoint 1 encountered at 0x08048088 eax = 0x00000004 ebx = 0x00000001 ecx = 0x08049098 edx = 0x0000000F esp = 0xBFFFF6C0 ebp = 0x00000000 esi = 0x00000000 edi = 0x00000000 ds  = 0x0000002B es  = 0x0000002B fs  = 0x00000000 gs  = 0x00000000 ss  = 0x0000002B cs  = 0x00000023 eip = 0x08048088 eflags = 0x00000246 Flags: PF ZF IF 08048088  CD80                       int 0x80     如果需要对汇编代码进行单步调试,可以使用 next 命令: ald> next Hello, world! eax = 0x0000000F ebx = 0x00000000 ecx = 0x08049098 edx = 0x0000000F esp = 0xBFFFF6C0 ebp = 0x00000000 esi = 0x00000000 edi = 0x00000000 ds  = 0x0000002B es  = 0x0000...

Linux汇编语言开发初探(1)

一、简介     作为最基本的编程语言之一,汇编语言虽然应用的范围不算很广,但重要性却勿庸置疑,因为它能够完成许多其它语言所无法完成的功能。就拿 Linux 内核来讲,虽然绝大部分代码是用 C 语言编写的,但仍然不可避免地在某些关键地方使用了汇编代码,其中主要是在 Linux 的启动部分。由于这部分代码与硬件的关系非常密切,即使是 C 语言也会有些力不从心,而汇编语言则能够很好扬长避短,最大限度地发挥硬件的性能。     大多数情况下 Linux 程序员不需要使用汇编语言,因为即便是硬件驱动这样的底层程序在 Linux 操作系统中也可以用完全用 C 语言来实现,再加上 GCC 这一优秀的编译器目前已经能够对最终生成的代码进行很好的优化,的确有足够的理由让我们可以暂时将汇编语言抛在一边了。但实现情况是 Linux 程序员有时还是需要使用汇编,或者不得不使用汇编,理由很简单:精简、高效和 libc 无关性。假设要移植 Linux 到某一特定的嵌入式硬件环境下,首先必然面临如何减少系统大小、提高执行效率等问题,此时或许只有汇编语言能帮上忙了。     汇编语言直接同计算机的底层软件甚至硬件进行交互,它具有如下一些优点: 能够直接访问与硬件相关的存储器或 I/O 端口; 能够不受编译器的限制,对生成的二进制代码进行完全的控制; 能够对关键代码进行更准确的控制,避免因线程共同访问或者硬件设备共享引起的死锁; 能够根据特定的应用对代码做最佳的优化,提高运行速度; 能够最大限度地发挥硬件的功能。     同时还应该认识到,汇编语言是一种层次非常低的语言,它仅仅高于直接手工编写二进制的机器指令码,因此不可避免地存在一些缺点: 编写的代码非常难懂,不好维护; 很容易产生 bug,难于调试; 只能针对特定的体系结构和处理器进行优化; 开发效率很低,时间长且单调。     Linux 下用汇编语言编写的代码具有两种不同的形式。第一种是完全的汇编代码,指的是整个程序全部用汇编语言编写。尽管是完全的汇编代码,Linux 平台下的汇编工具也吸收了 C 语言的长处,使得程序员可以使用 #include...

贝叶斯定律通俗理解 (Z)

18世纪,英国学者贝叶斯(1702~1761)曾提出计算条件概率的公式用来解决如下一类问题:假设H[,1],H[,2]…互斥且构成一个完全事件, 已知它们的概率P(H[,i],i=1,2,…,现观察到某事件A与H[,1],H[,2]…相伴随而出现,且已知条件概率P(A/H[,i]),求 P(H[,i]/A)。贝叶斯公式(发表于1763年)为: P(H[,i]/A)=P(H[,i])P(A/H[,i])/[P(H[,1])P(A/H[,1]) P(H[,2])P(A/H[,2])…]   这就是著名的“贝叶斯定理”,一些文献中把P(H[,1])、P(H[,2])称为基础概率,P(A/H[,1])为击中率,P(A/H[,2])为误报率[1]。现举一个心理学研究中常被引用的例子来说明:   参加常规检查的40岁的妇女患乳腺癌的概率是1%。如果一个妇女有乳腺癌,则她有80%的概率 将接受早期胸部肿瘤X射线检查。如果一个妇女没有患乳腺癌,也有9.6%的概率将接受早期胸部肿瘤X射线测定法检查。在这一年龄群的常规检查中某妇女接受 了早期胸部肿瘤X射线测定法检查。问她实际患乳腺癌的概率是多大?   设H[,1]=乳腺癌,H[,2]=非乳腺癌,A=早期胸部肿瘤X射线检查(以下简称“X射 线检查”),已知P(H[,1])=1%,P(H[,2])=99%,P(A/H[,1])=80%,P(A/H[,2])=9.6%,求P(H[,1] /A)。根据贝叶斯定理,P(H[,1]/A)=(1%)(80%)/[(1%)(80%) (99%)(9.6%)]=0.078 其实,即使我们没有学过贝叶斯定律,也可以解决上述的问题。 如果患病和没有患病的人概率分别问 1%和 99%, 患病检查的概率和没有患病但是也检查的概率分别为80%和 9.6%。 那么我们做如下假设: 有10000个人, 其中100个为患病者;有80+950.4的人接受了检查,其中950.4为9900人中接受检查的人。 那么我们可以知道对于这10000人里面的一个, 如果她是来接受检查的1030人里面的一个,那么她属于患病的80人中的一个的概率就是80\1030,而这,就是贝叶斯定律给我们的答案。