posted in 操作系统 

操作系统引导

从用户按下计算机电源开关开始,到操作系统运行起来这段时间被称为“系统引导(boot)”,一般的操作系统理论都不将它看做操作系统的一部份,因 而很多操作系统教科书都这部份只字未提。但是从开发操作系统的角度来看,“引导”是非常重要的一个环节。因为,你开发的操作系统正是经过“引导”程序读进 内存,然后才开始工作的。因此,要想开发一个操作系统,了解“引导”过程,是非常必要的。

  “引导”过程与计算机硬件密切相关,这里只针对最常见的Intel x86及IBM PC体系结构进行描述,其余硬件平台的“引导”进程请参见相应资料。

 

 

第一条指令的地址

  在用户按下计算机电源开关之后,CPU会自动的将其CS寄存器设定为0xFFFF,将其IP寄存器设定为0x0000。由于CS:IP指出了下一条指令的地址[1],因此CPU会跳到0xFFFF:0x0000处进行执行。为什么是这个地址而不是其它地址呢?这其实是一个很巧妙的设计。

  我们知道,从80386开始,到后面80486、奔腾,它们都是32位的CPU,但是它们都与Intel先前开发的8086兼容。也就是说,在默认情况下,80386、80486等,只不过是一台运行得更快一些的8086罢了。因此,这里我们只讨论8086[2]

  8086是16位的CPU,但是却有20根地址线[3]。也就是说它可以寻址220 = 1M 内存空间。这段内存空间由RAM、ROM组成。ROM是随机只读存储器,里面的程序是在计算机出厂的时候直接烧录在里面的,完成一些主机自检等操作,并提 供一些访问磁盘等基本输入输出服务,因而这段程序常被称为BIOS(Basic Input/Ouput Service)。由于不同的计算机厂商生产的计算机所带的外设不一样,因此,这段程序大小也限机型的不同而不一样,有可能A厂出产的计算机所带的这段程 序的大小为1K,而B厂出产的这段程序的大小为2K。如果将这段程序放在0x0000处,那么用户写的程序就可能从0x0400处开始也可能从 0x0800处开始,非常不统一。故而,将此段程序放在1M内存的顶部,那么用户写的程序就都可以从0x0000处开始了。

  但将BIOS这段程序放在1M内存的顶部,如果这段程序大小为1K,那么应当从0xFFC00开始放。如果这段程序的大小为2K,那 么应当从0xFF800开始放,对于CPU而言,到底是应当从0xFFC00开始执行还是应当从0xFF800开始执行呢?为了解决这个问题,8086规 定,CPU均从0xFFFF0处开始执行,而在0xFFFF0处,放一条无条件转移指令JMP。如果A厂的BIOS是从0xFFC00开始放的,那么这条 转移指令就跳转到0xFFC00处开始执行。如果B厂的BIOS是从0xFF800开始放的,那么这条转移指令就跳转到0xFF800处开始执行,各个厂 家可以跟据自己所生产的BIOS程序的大小,来决定此转移指令具体跳转到的位置。

  这里有一点需要清楚的是,通常认为,内存编址是连续的,不会出现空洞,其实完全不是这样。比如,假设BIOS的编址是从 0xF0000开始,而RAM,即通常讲的内存编址是从0x00000开始,那么,如果用户只安装了32K内存,那么内存的编址范围就是 0x00000~0x07FFF,那么从0x08000至0xEFFFF处就没有安装内存,这就是一个内存空洞。

  好了,当CPU执行了放在0xFFFF0处的第一条指令后,就跳转到BIOS程序内部去执行了,下面就来看看BIOS都做了些什么。

 

[ 编辑]

 

BIOS的工作

  BIOS的工作相当简单,主要的工作就是执行主机自检(POST),然后查找操作系统存在在哪个磁盘上,将操作系统载入。BIOS在查找各磁盘 的操作系统时,主要是查找磁盘上的第一个扇区(0面0磁道1扇区),每个扇区是512字节,如果这是一个引导扇区,那么就将它载入0x7C00的内存地址 上,然后跳转到此地址上执行。如果此不是一个引导扇区,就继续查找下一个磁盘,看其上面是否存在引导扇区。如果所有的磁盘上都不存在引导扇区,则在屏幕上 打印出一条出错信息。

 

[ 编辑]

 

引导扇区的工作

  引导扇区只有一扇区即512字节大,因此它的主要目的是把操作系统的内核读进内存,然后跳转到操作系统内核处开始执行。从编写操作系统角度来 说,前面的CPU上电及BIOS的工作都不是操作系统能控制的,而从引导扇区开始,就完完全全可由操作系统来控制了,因此,编写引导扇区也是编写操作系统 必要的工作之一。从BIOS跳入引导扇区后,计算机系统引导工作就算完成,怎样把操作系统内核读进内存,然后再安排一条跳转指令跳到内核处执行就是操作系 统开发人员的工作了。

 

[ 编辑]

 

其它资源

  • 对于引导过程更详细的描述及示例程序可以参见谢煜波的《操作系统引导探究》。

 

转自:

人走茶凉

http://blog.163.com/terrcy.j@126/blog/static/49300638200798445695/

 

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/8821377

posted in 数据库 

由于工作需要,今天要在电脑上安装SQL Server 2005。以往的项目都是使用Oracle,MS的数据库还真的没怎么用过,安装Oracle已经轻车熟路,但装SQL Server好像还有点小麻烦,所以记录下来,以留备用。

-------------------------------------------------------------------------------------------------

操作系统:Microsoft Windows 7 旗舰版(32位)

数据库版本:SQL Server 2005 简体中文开发板

数据库下载链接:http://pan.baidu.com/share/link?shareid=322740&uk=268517599 (地址已更新2013-03-09)

-------------------------------------------------------------------------------------------------

安装过SQL Server的人可能知道,它的有些服务要依赖于IIS,所以为了保证数据库的顺利安装,先启用IIS服务吧!Win7比XP好的一点是:启用IIS功能无需借助系统安装盘了,只要在控制面板里启用即可,如图:

2011041813361136.png

step1

2011041813363315.png

step2

2011041813365645.png

第三步需要注意的是,选中红框中的复选项,分别为“Internet Information Services 可承载的 Web 核心”、“Web 管理工具”和“万维网服务”,这里我不确定“Web 管理工具”是否需要,因为我选中它们的父节点“Internet 信息服务”后选中了它的一些子项,多选总比少选全面,需要将它们的子项全部选中才显示为“√”,否则显示为“■”,记住,一定要显示为“√”才行,效果就 和step3一样就可以了!点击确定后会出现线面的框框

2011041813372698.png

如果我们不启用IIS功能,在后续安装SQL Server时会遇见如图画面

2011041813373551.png

到此,IIS功能就算启用完成了,下面开始安装SQL Server

 

安装文件解压后是一个ISO的镜像,其实是一个DVD文件,将两张光盘合并到一起了,所以你的电脑需要安装虚拟光驱,虚拟光驱不会用请先百度一下,我就不在这里赘述了。

首先启动虚拟光驱软件,把SQL Server的镜像加载进来,如图

2011041813384455.png

此时我们可以在我的电脑里看到这张虚拟的安装盘了,如图

2011041813390929.png

如果没有自动运行,那么我们就点双击H盘图标,进入安装

2011041813392995.png

紧接着进入如下画面

2011041813394889.png

我的系统是32位的,我自然选择基于x86的,之后点击“服务器组件、工具、联机丛书和示例(C)”

2011041813400755.png

紧接着弹出对话框,点击“运行程序(R)”

2011041813413248.png

接着出现,勾选,下一步

2011041813414696.png

安装程序会检查所需组件,点击“安装”

2011041813421091.png

点击“安装”

2011041813430715.png

2011041813432890.png

点击“下一步”后,安装程序会监测计算机配置

2011041813433974.png

紧接着跳转为安装向导

2011041813435723.png

点击“下一步”

2011041813441532.png

我们看到,所有的项目都成功,如果之前没有启用IIS功能的话,出现的画面就是之前的那个样子,点击“下一步”

2011041813443571.png

输入公司名后,点击“下一步”

2011041813445131.png

这里需要注意,如果你的界面只有最后一个复选框可选,其他都为灰色不可选,那说明你的版本有问题,不是开发版,请马上放弃安装,从上面我给的下载地址下载开发板进行安装。全部选中后点击“下一步”

2011041813462355.png

默认安装到系统盘下,我们可以点击高级进行修改,点击“浏览(R)”

2011041813463615.png

我将“C”修改成了“D”,点击“确定”

2011041813465686.png

点击“下一步”

2011041813471436.png

我选择的“默认实例”,也可以选择“命名实例”,点击“下一步”

2011041813473239.png

一切默认,点击“下一步”

2011041813474966.png

因为其他程序也可能连接数据库,所以选择“混合模式”,并键入sa密码,点击“下一步”

2011041813480873.png

默认,点击“下一步”

2011041813482818.png

默认,点击“下一步”

2011041813484334.png

默认,点击“下一步”

2011041813485714.png

漫长的安装才刚要开始,点击“安装”

2011041813500879.png

该过程很耗时,慢慢等待吧

2011041813502038.png

安装中途,遇到的第一个弹出窗口,点击“运行程序(R)”

2011041813503639.png

安装了一会,结果又弹出,继续点击“运行程序(R)”

2011041813505289.png

所有模块都安装完毕了,点击“下一步”

2011041813510930.png

到这里就接近尾声了,点击“完成(F)”

2011041813512441.png

 

这个界面是登陆到刚刚安装的数据库,因为安装的时候我们使用的是“默认实例”,也就是计算机名称,“IceWee-PC”是我的计算机名称,点击连接就登陆到数据库了。

我个人感觉安装SQL Server需要注意的地方有两点,一是IIS功能的启用,二是一定要选对安装版本,我第一次就下错了,下的企业版,结果
就只能安装“工作站组件、联机丛书和开发工具”。

 

关于局域网内其他计算机要连接上这个数据库我也遇到了点小麻烦,折腾了半天才搞定。

首先,系统防火墙和其他第三方防火墙,如360、QQ电脑管家、杀毒软件等,这个是常识了

其次,使用telnet命令进行连接,如果能够连上,那么肯定就能访问了,命令格式:

telnet 数据库IP 1433

连不上就会出现如下画面

2011041813514176.png

 

就为了能telnet上我的数据库,折腾了半天啊!折腾了半天!哈哈,最后终于解决了

开始-》Microsoft SQL Server 2005-》配置工具-》SQL Server Configuration Manager

 在弹出窗口中,按照下图点开左侧树

2011041813523257.png

我们看到红框中的“TCP/IP”协议是“已禁用”状态的,我们把它启用后,再重启SQL Server就能telnet上了!

 

转自:

ice world

http://www.cnblogs.com/icewee/articles/2019783.html

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/8811090

posted in 操作系统 

Memory Map (x86)

Revision as of 05:41, 22 May 2012 by  Amirsaniyan  (Talk | contribs)

( diff← Older revision | Latest revision (diff) | Newer revision → (diff)

This article describes the contents of the computer's physical memory at the moment that the BIOS jumps to your bootloader code.

Contents

 [hide

"Low" memory (< 1 MiB)

When a typical x86 PC boots it will be in Real Mode, with an active BIOS. During the time the CPU remains in Real Mode, IRQ0 (the clock) will fire repeatedly, and the hardware that is used to boot the PC (floppy, hard disk, CD, Network card, USB) will also generate IRQs. This means that during the PC boot process, the Real Mode IVT (see below) must be carefully preserved, because it is being used.

When the IVT is activated by an IRQ, it will call a BIOS routine to handle the IRQ. Bootloaders will also access BIOS functions. This means that the two memory workspaces that the BIOS uses (the BDA and the EBDA) must also be carefully preserved during boot. Also, every time the BIOS handles an IRQ0 (18 times a second), several bytes in the BDA get overwritten by the BIOS -- so do not attempt to store anything there while IRQs are active in Real Mode.

After all the BIOS functions have been called, and your kernel is loaded into memory somewhere, the bootloader or kernel may exit Real Mode forever (often by going into 32bit Protected Mode). If the kernel never uses Real Mode again, then the first 0x500 bytes of memory in the PC may be reused and overwritten. (However, it is very common to temporarily return to Real Mode in order to change the Video Display Mode.)

When the CPU is in Protected Mode, System Management Mode (SMM) is still invisibly active, and cannot be shut off. SMM also seems to use the EBDA. So the EBDA memory area should never be overwritten.

Note: the EBDA is a variable-sized memory area (on different BIOSes). If it exists, it is always immediately below 0xA0000 in memory. It is absolutely guaranteed to be less than 128 KiB in size. It is often 1 KiB. The biggest ones ever actually seen are 8 KiB. You can determine the size of the EBDA by using BIOS function INT 12h, or (often) by examining the word at 0x40E in the BDA (see below). Both of those methods will tell you the location of the bottom of the EBDA.

It should also be noted that your bootloader code is probably loaded and running in memory at physical addresses 0x7C00 through 0x7DFF. So that memory area is likely to also be unusable until execution has been transferred to a second stage bootloader, or to your kernel.

Overview

start end size type description
Low Memory (the first MiB)
0x00000000 0x000003FF 1 KiB RAM - partially unusable (see above) Real Mode IVT (Interrupt Vector Table)
0x00000400 0x000004FF 256 bytes RAM - partially unusable (see above) BDA (BIOS data area)
0x00000500 0x00007BFF almost 30 KiB RAM (guaranteed free for use) Conventional memory
0x00007C00 (typical location) 0x00007DFF 512 bytes RAM - partially unusable (see above) Your OS BootSector
0x00007E00 0x0007FFFF 480.5 KiB RAM (guaranteed free for use) Conventional memory
0x00080000 0x0009FBFF approximately 120 KiB, depending on EBDA size RAM (free for use, if it exists) Conventional memory
0x0009FC00 (typical location) 0x0009FFFF 1 KiB RAM (unusable) EBDA (Extended BIOS Data Area)
0x000A0000 0x000FFFFF 384 KiB various (unusable) Video memory, ROM Area

BIOS Data Area (BDA)

The BDA is only partially standardized, and almost all the values stored there are completely obsolete and uninteresting. The following is a partial list. See the External Links references below for more detail.

address (size) description
0x0400 (4 words) IO ports for COM1-COM4 serial (each address is 1 word, zero if none)
0x0408 (3 words) IO ports for LPT1-LPT3 parallel (each address is 1 word, zero if none)
0x040E (word) EBDA base address >> 4 (usually!)
0x0410 (word) packed bit flags for detected hardware
0x0417 (word) keyboard state flags
0x041E (32 bytes) keyboard buffer
0x0449 (byte) Display Mode
0x044A (word) number of columns in text mode
0x0463 (2 bytes, taken as a word) base IO port for video
0x046C (word) # of IRQ0 timer ticks since boot
0x0475 (byte) # of hard disk drives detected
0x0480 (word) keyboard buffer start
0x0482 (word) keyboard buffer end
0x0497 (byte) last keyboard LED/Shift key state

Extended BIOS Data Area (EBDA)

You may see "maps" of the EBDA if you search the web. However, those maps are for the original IBM BIOS EBDA. They do not apply to any current EBDA, used by any current BIOS. The EBDA area is not standardized. It does contain data that your OS will need, but you must do a bytewise pattern search to find those tables. (SeePlug-and-Play.)

ROM Area

start end size region/exception description
Standard usage of the ROM Area
0x000A0000 0x000BFFFF 128 KiB video RAM VGA display memory
0x000C0000 0x000C7FFF 32 KiB (typically) ROM Video BIOS
0x000C8000 0x000EFFFF 160 KiB (typically) ROMs and unusable space Mapped hardware & Misc.
0x000F0000 0x000FFFFF 64 KiB ROM Motherboard BIOS

"Upper" Memory (> 1 MiB)

The region of RAM above 1 MiB is not standardized, well-defined, or contiguous. There are likely to be regions of it that contain memory mapped hardware, that nothing but a device driver should ever access. There are likely to be regions of it that contain ACPI tables which your initialization code will probably want to read, and that then can be overwritten and reused. Some ACPI areas cannot be "reclaimed" this way. Some of the computer's RAM may extend above 4 GiB.

Use the BIOS function INT 15h, EAX=0xE820 to get a reliable map of Upper Memory.

start end size region/exception description
High Memory
0x00100000 0x00EFFFFF 0x00E00000 (14 MiB) RAM -- free for use (if it exists) Extended memory 1, 2
0x00F00000 0x00FFFFFF 0x00100000 (1 MiB) Possible memory mapped hardware ISA Memory Hole 15-16MB 3
0x01000000  ????????  ???????? (whatever exists) RAM -- free for use More Extended memory 1
0xC0000000 (sometimes, depends on motherboard and devices) 0xFFFFFFFF 0x40000000 (1 GiB) various (typically reserved for memory mapped devices) Memory mapped PCI devices, PnP NVRAM?, IO APIC/s, local APIC/s, BIOS, ...
0x0000000100000000 (possible memory above 4 GiB)  ????????????????  ???????????????? (whatever exists) RAM -- free for use (PAE/64bit) More Extended memory 1
 ????????????????  ????????????????  ???????????????? Possible memory mapped hardware Potentially usable for memory mapped PCI devices in modern hardware (but typically not, due to backward compatibility)

1: Different computers have different amounts of RAM, therefore the amount of extended memory you might find will vary and may be anything from "none" (e.g. an old 80386 system) to "lots".

2: Free for use except that your bootloader (ie. GRUB) may have loaded your "modules" here, and you don't want to overwrite those.

3: The "ISA Memory Hole" (from 0x00F00000 to 0x00FFFFFF) was used for memory mapped ISA devices (e.g. video cards). Modern computers have no need for this hole, but some chipsets still support it (as an optional feature) and some motherboards may still allow it to be enabled with BIOS options, so it may exist in a modern computers with no ISA devices.

转自: http://wiki.osdev.org/index.php?title=Memory_Map_(x86)&oldid=13415

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/8811060

posted in 网络 

      如何在宿舍通过电脑访问控制自己放在实验室的电脑?

    主要总结了 telnet服务、ftp服务、共享文件夹、远程桌面连接 几种方法。

 

1. telnet服务

    优点:操作简便、通用性强

    缺点:不能上传下载文件,只能远程设置主机(可以通过访问自己FTP服务实现上传下载,不过很麻烦)。

    使用方法:

           被控主机:控制面板打开 telnet服务器 服务;在 用户组 TelnetClients 中添加用户;

           控制主机:在客户端控制面板中打开 telnet客户端 服务;在 cmd 中用telnet命令即可。

 

2. FTP服务

    优点: 方便直观的上传下载文件。

    缺点: 要下载的文件需要提前放到 FTP文件夹中。

    使用方法:

           被控主机:控制面板中打开 FTP服务;在 我的电脑——右键——管理——IIS 中设置FTP相关设置。

           控制主机:IE中ftp访问即可。

 

3. 共享文件夹

    优点: 可以映射网络驱动器,使用特别方便

    局限: 要求在同一个局域网中

 

4. 远程桌面

    优点: Microsoft自带软件,通用性强;功能强大

    缺点: 待测。

 

 

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/8769281

posted in 程序员之路 

引子

唉,本实在不想发水文的,可还是发了,看来是周末闷骚咯,没兴趣的请赶紧飘过 ~~~

本篇博文其实是用来给在读大学生一点借鉴的,并不会讨论什么技术类的点 ,所以,不喜欢这种类型文章的也可以飘过,

但是如果各位有兴趣的且保有不同意见者,也可以提出,欢迎讨论,毕竟出来混的应该也看过了很多学校里所谓的大学生,

估计心里头对现在从大学里头招进来的各位小学弟小学妹也不咋的满意,而我也算是比较了解一些学生的,

所以,何不趁着周末一起出来指点一下他们呢?

                

           

致学生 - 大学最重要的不是 Java 和 .Net 而是基础,基础才是最重要的 !!!

在这里,我也主要是因为见很多大学生现还在学校里迷茫,毫无方向感,

而刚好自己周末有点闷骚吧,因此也站出来说两句话,希望不会因此受到人身攻击,

当然,我只是扯淡,说出我的建议,至于觉得发言不妥者,自可以飘过,也欢迎提出新的见解,

而这里我对大伙扯的两句,尤其适用于现还在大学里的各位学弟学妹们,

首先,现在大学里过多追求就业率,拿我们学校来说吧,是个二流学校,为了有好的就业率,

学校一直和校外培训机构进行合作,一直主推 Java ,甚至推出学生如果在某个培训学校培训的话,

是可以不用去上课的,这一点,我实在想不通,最后我给自己一个答案,那就是学校已经自认为比不上外面的培训机构了,

这个不得不说是一个悲剧哦 ! ! !

而后就是,我们学校里,好不容易有个博导给我们上课,但是悲剧又来了,博导上的课居然是计算机导论,

最差劲的一门了,唉,现在才发现,大学里真正教书的一般都是助教和讲师,博导可都是有自己的项目要做,

有自己的公司要开,有自己的人际网要拓展,博导这么忙,当然也就只能请个助教了,

这个其实才是现今大学教学的一个大悲剧 ! ! !

还有就是我本科学的是软件工程,大学里,我很悲剧我没有学过组成原理,编译原理等等基础课,

我们听讲座听的最多的居然是培训学校来的老师的演讲(基本上是推销),

呵呵,够悲剧了吧,希望各位的学校不会和我们学校一样 . . .

上面呢,就是我在学校时候的学习背景了。

          

然后呢,我再根据我自己的经历来谈谈我的看法,我呢,也算是个计算机行业的狂热分子吧,

自大一接触  C++ ,我一直都对这行业很感兴趣,曾经也经常在网吧上通宵(当然那会是为了学习  C++ ),

大一到大二上学期,我一直都是在黑框框里面(也就是 DOS 环境下)写着 C++ 程序,

也潜心写过汉诺塔,迷宫,八皇后等等经典算法题,

那会儿写的呢也很带劲,但一直没有接触过具体界面的实现,所以总是感觉有些不爽,因为总觉得那不是软件,

甚至都怀疑起  C++ 到底能够做什么用,现在想来那时候的想法真是幼稚啊,

并且自己也总是幻想着能够什么时候做一个具体的软件出来(那个时候总是觉得只有有了现在所谓的图形界面才算得上软件),

后来一次偶然的机会,我接触了 . Net ,然后,我发现,做图形界面是如此的爽呼呼,

于是乎,一个人拼命地学,拼命地学 .Net,然后开始拼命地写我那个时候我所认为的所谓的软件,

写一些数学工具,一些小游戏,也将一些诸如迷宫,八皇后的算法题从 C++ 改成 C# 写的应用程序,

然后就是做  Web  开发,学了很多很多,也做了很多的诸如什么什么的管理系统等等,

但一直都感觉不再向大一学习  C++ 那么正派了,有点说不出的感觉,

但也一直总结不出什么内容,

不过现在算是总结出来了,因为我过早的涉及了高级语言,而忽略了真正的基础  ! ! !

因为总结出来了结果,所以我也越发的思考大学里面,作为一个大学生到底应该要学的是什么?

总结了个人所认为的在技术上的几点内容,注意是技术上的,至于做人处事上的,我自己都做的不好,没资格在这里扯淡,

英语很重要,我的英语一直不怎么的,因为英语差劲我也吃了很多亏的,甚至我现在看英文资料,我都得开着金山词霸的划词翻译,

看起来的那个速度自然是不用说了,

曾经我也总是想,现在国内资料那么多,要英语干吗?呵呵,听我一句劝,好好学习英语吧,

因为你会发现,你真正要找的资料是某个不常用  API  的英文解释,而不是要找  HelloWorld  怎么实现的中文资料,

然后就是难道你以为任何一门语言都有向  MSDN  中  C#  这么全面的中文文档?那你看看  MSDN  中 VC++ 的文档吧 ! ! !

或许有人会说:为什么  C/C++  中文资料这么多?

天呐,难道你想一辈子跟在别人几十年后面,你知道  C/C++ 是一年出来的吗?难道,你愿意永远比别人了解到新知识晚几十年?

数学很重要,大学里,我数学一直都还不错,无论是高数,还是线数,离散,我都学得不错,也一直有些沾沾自喜,

但是到现在看来,我的数学,呵呵,悲剧,学得太烂了,数学的话,我觉得各位在校的,也听一句劝,学得越深越好,

曾经,我也总是觉得数学没一点用处,但是后来看了  OpenCV ,也和同学讨论了  OpenGL ,谈论了一些计算机图形学的内容,

也看了同事的一些不晓得是什么的东西,居然列那么多数学公式,关键是我一个都不懂,

此时我才发现,计算机的世界其实是一个数学世界,

你想深入了解计算机,那你得数学得学得非常牛逼,里头全是数学,所有的东西都是数学,

甚至让我觉得,计算机搞到很牛逼了的话,那么一定可以成为一个牛逼的数学家了,

或许各位会说,我只局限在我所了解的领域里面了,因为在  .Net 中,数学似乎一点都不重要呢,

但是我会反问,难道你又不是局限在 .Net  中了,

或许,你觉得微积分,常微分方程离我们很远,其实,你错了,它离我们很近,你总有一天会发现的,

呵呵,其实数学的重要不重要,关键在于你想不想真正的呆在这一行里面;

汇编很重要,弄到这里,应该会有很多人反对了,因为,向汇编这种东西,在搞 Java  和 .Net 的这些高级语言程序员眼里,

那早就应该是过时的内容了,呵呵,其实我以前也是这么觉得的,毕竟,有本事你拿汇编做个  Web 应用程序出来看看,

呵呵,以前多幼稚的想法啊,人家<<疯狂程序员>>里头的绝影就是弄的汇编,不晓得现在混得咋样咯,应该不会差那头去吧,

毕竟人家弄的是汇编,确实,那汇编做应用软件或者 Web 应用程序的话,确实太牵强了,但是为何我现在搞 .Net 这么多年了,

反而回过头来学习汇编了呢?因为我发现,我对内存的管理,对寄存器中的内容,对整个 .Net  的底层,对所有的一切都掌控不了,

曾经看一本书,好像是<<Sql  Server  2005  高级程序设计>>吧(一本  Sql  Server  方面的巨著,这里擅自推荐一下),

里面的作者就说了,计算机中最害怕的事情就是不可预料,无法掌控,

而且汇编语言中,对内存的寻址,以及寄存器的使用都有非常好的解释和频繁的使用,

通过学习汇编,你可以更好的理解地址总线,数据总线,控制总线和 CPU 以及内存之间真正的工作流程,

以及它们之间的一些最基层的协作关系,同时也能理会内存最真实的使用,

而不会向无头苍蝇一样,甚至连内存是什么都不知道,只会说,我只要分配内存即可,只要  new  就 OK 了,

当然如果你只想做到你所要的  new  的话,我也没有办法,我只能说你还不够狂热,不够专业,不是合格的程序员;

计算机组成原理和编译原理,计算机组成原理的重要性是不言而喻的,毕竟考研专业课中,这东西好像还占蛮大的比例的,

至于这编译原理吗,肯定又有人反对编译原理了,说,又不让你自己搞编译器,学什么编译原理,

呵呵,说的也不错,但是我想说的是,并不是你想搞什么你才去学什么,眼光放远点,

你会发现,你的世界里并不是只有 .Net  和 Java,

而且在编译原理这东西里面,你确实能够学到很多东西,就比如,如果当初设计  Java  的是你,

你会想到先将程序编译成字节码,然后再使用解释器来解释字节码吗?

我想,你肯定想不出的 ~~~

操作系统

操作系统,这个名词听着都感觉很严重,毕竟,在操作系统被  Windows  垄断的环境下,

也确实很难有人愿意接受操作系统是很重要的东东了,

甚至觉得学习操作系统就是学习如何在  DOS  环境下,敲个命令出来一大堆东西,

或者觉得学习操作系统就像是学习  <<Windows  操作系统一千招>>一样,

能够打开个注册表,能够优化一下电脑,改变一下电脑启动画面,那就是学习操作系统了,

又觉得以后操作系统这东西就给微软去做吧,

如果你真这样想的话,那我只能说,真是个悲剧 ! ! !

我想说,如果你觉得操作系统不重要的话,那你真是错到家了,

大学里头,我一开始也是带着混的心态混过的操作系统课程的,

但是在考试前一个星期,我居然迷恋上了操作系统,那可真是作死的看操作系统啊,

整整在一个星期里,我拿着<<操作系统概念>>看了 2 遍,甚至在看完 2 遍中文版的之后,

我还准备去啃原版的,无奈英文水平太差,最后只能作罢,

经过了那次的操作系统的学习后,我自以为操作系统我掌握的还不错了,

但是后来,我发现,我一直都在追赶操作系统里面的知识,

从我写驱动程序开始,我就一直在追赶操作系统,为此,我重新学习操作系统,看  Windows  内核原理,

看  Windows  分析,看内存管理,看进线程调度,看  CPU  调度,看  I/O 管理,即插即用管理等等,

看了很多,至今我都觉得,我在操作系统这一块还很欠缺,很欠缺,我越往深处学习,我就觉得我越欠缺操作系统的知识,

现在也还正在打算到哪里再去找些什么资料来填补空缺呢,呵呵,说了这么多,

我只是想纠正现在大学里头很多人认为操作系统不重要这一观念,

操作系统真的很重要,很重要 ! ! !

C/C++,这两个东西我想不必多说了,只是在这里奉劝那些和我当年幼稚想法一样的说  C/C++ 做不了什么用的人,

如果这两个东西,你错过了,你补都补不回,

其实啊,我们被大学里头的老师害惨了啊,

曾经我的  C++ 老师就说,美国什么航空火箭发射上天后失败,直接掉了下来,照成  n  人死亡,损失惨重,

而这一切竟然是一个指针惹的祸,所以,我们  C++  老师就跟我们说,指针这个东西很危险,少接触为妙,

哈哈哈,真被害惨了,后来才发现 C/C++ 如果没有了指针,那就真的一点用处都没有咯 ~~~

还有,当年老师教  Goto  语句的时候,老师只讲了一句话:这东西,影响程序逻辑性,造成程序可读性差,所以大家禁用 ~~~

呵呵,现在出来,这个  Goto 语句也还是经常看到的

(这里我并不是推广使用  Goto 语句哦,只是有些东西,并不是说老师不教我们就可以不学的,也不是我们不学,以后就不会碰到要使用的情况的)

劝诫各位,千万不要看不起黑框框,来句形象点的:一切图形界面都是过眼浮云 ~~~

我最庆幸的是,我当初对 C++ 还执着过那么一年半,所以,也还算有一点点,也就是一点点底子而已,

拿最简单的说,人家  Windows  还是 C 写的呢,人家  Oracle  也是  C  写的呢,你还敢说  C/C++ 没用 ?

然后,那你又会说,那些都是做的系统集成,系统软件,

呵呵,那我现在给公司里写的也都是  C  写的呢,而且写的环境还是在黑框框里头写的呢 (Dos  环境下编译调试),

那你现在还会很鄙视黑框框吗 ?

数据结构和算法,对数据结构还好,在大学里,还是有很多人意识到了数据结构的重要性的,

而且,基本上上课的老师也会稍微强调一下数据结构的重要性,呵呵,所以,在大学里头,这门课缺课的人还是比较少的,

确实,如果等到各位将来研究一些稍微底层的代码时,或者如果有机会写系统软件的时候,

你会发现,底层里头的链表那个多啊,循环链表,双向循环链表,平衡数,顺序表,最小生成树等等用的到处都是,

当然啦,现在 C# 里头,大家或许很少有机会接触到了,要队列有队列,要表有表,要字典有字典,要什么有什么,

一般来说一个字典,一个  Array , 一个泛型基本上全部搞定,

但是忘了告诉各位,用得这么方便可是需要付出代价的哦  ! ! !

而对于算法的话,现在感觉越来越不受重视了哦,

甚至很多学校都不开算法课了,只是一个简单的数据结构带过而已,

所以很多人也都不晓得贪心算法,动态规划等了(说实话,我也不太懂了,不过打算有时间去补补),

都是高级语言惹得祸(注意,这里不是抨击高级语言哦),把算法都封装的那么好,

说实在的,如果真不做大的系统的话,算法这东西真的很多都可以不需要掌握了的,

但是,如果,这世界上每一个人都这样想的话,就不会有  Windows  ,Oralce 了,

殊不知,Windows  整个结构的复杂性,其中调度算法的使用,

也殊不知,Oracle  体系结构的复杂度,其中缓存处理算法的复杂度等等,

如果你只想在  .Net  上用用别人的东东,或者说是有空拿个循环玩玩的话,算法这东西确实跟你隔得很远了,

但是,难道你愿意这样???

你去看现在年薪高的程序员,哪一个不是算法高手?

呵呵,这就是差别哦  ~~~

数字电路和模拟电路,说到这里,更多意见应该会冒出来了,咱搞软件的,为什么要搞这些东西呢?

呵呵,如果真的不用搞这些东西,大学里就不会开这些课咯,博客园里头搞 .Net  的居多,搞  Web 开发和 .Net 应用软件开发的居多,

而现在市场上搞  Java  和  .Net 的又是居多,所以设计到数字电路和模拟电路的内容不多,

甚至是一片空白,所以也就觉得这两东西真是扯淡,说真的,我很能体会大伙的心情,因为我以前也是这样觉得的,

但是,大家眼光放开点,真的放开点,这个世界上真的就只有  Java  和 .Net 了吗?

而除了  Java  和  .Net  以外,很多其他地方,对于数字电路和模拟电路都是要求很高的,

尤其现在社会上很缺模拟电路方面的人才哦,而且,理解了这两个东西以后,对于自身理解程序的具体怎么跑的,

为什么能输出个字符,为什么能执行计算操作都是很有帮助的,而不会像一个码农,连自己在做什么都不知道,

这也就是所谓的不可预知 ! ! !

计算机网络,这个东西呢,说真的,也不好说,当今早就过了以前那个计算机只是用来做计算的时代了,

现在是网络的时代,如果你真不懂网络,说实在的,你连程序员都不适合,不要求你有多深的掌握,

但是  TCP,UDP 还是要分得清吧?TCP/IP 协议五层结构总的知道吧?

数据具体的流动过程也要有所了解吧,呵呵,都是很基础的东西啊,

可是,这些基础却是最重要的东西~~~

 

                       

总结

上面总结出来的几门课程,都是我认为大学里头,在计算机中最最基础的课程了,

但是,这些课程却被很多大学给忽略了,从而也被很多大学生给忽略掉了,

而诸如软件工程,数据库,软件项目管理之类的课程我在这里没有提及,因为,那一块过多涉及软件方向了,

会限制到一些思维,所以我没有提及。

现在的大学里(像我所在的学校),侧重点已经变咯,培养学生事小,捞到收入才是最重要的了,

学校为什么拼就业率啊?就业率高了,自然学生来得多,学生来得多,自然,国家给的钱多,

自然,腰包里钱更多,然后又大肆拼就业率,拼就业率,那就得多让学生接触所谓的现在社会上所需要的(Java  和  .Net  程序员),

如何培养出这样的程序员呢?交给培训学校吧 . . .

甚至,似乎今年还推出了一个新的专业,是和牛耳培训学校合作的一个软件外包专业,

呵呵,专业外包人才,靠 . . . 名字真好听 . . . 要我说,学校太不负责了 . . .

说实在的,以前,有一些不同意老赵对培训学校的观点的,

但是,现在看来,也还是有一些同意了(但培训学校确实还是有一些作用的,或许会培养人,但是我觉得也会害死人),

通观全文,可能有读者会觉得我在反对高级语言,其实,我一直都在努力地避开这个话题,

因为,我本身的意愿并不是反对高级语言,只不过,我觉得大学里头的学生,

尤其是大一,大二,大三的学生,他们不应该过早的接触到高级语言,

如果他们基础真的好了,那他们到哪里都可以展翅,当然,等到基础好了,

学起高级语言来也是手到擒来的 . . .

还有就是需要解释一下,现在大学里头流传的:学基础课程是找不到工作的 !只有  Java  和  .Net  才是王道;

我的回答是放屁 !

           

好了,拍砖的拍砖,要骂的请先给出理由,然后再骂,最讨厌什么都不标明就进行人身攻击者 !

          

同意的请顶起,反对的请说出理由,也算是给学弟学妹们一个指导 !

         

          

欢迎转载,但转载请注明:     转载自    Zachary.XiaoZhen - 梦想的天空

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/8759243

posted in OJ题解 

#include <stdio.h>

int max(int a[100], int n)	//求最高层数
{
	int highest;
	int i;

	highest = a[0];

	for (i = 1; i < n; i++)
	{
		if (a[i] > highest)
			highest = a[i];
	}

	return highest;
}

int count_time(int n, int a[100], int highest)//计算每组测试需要的总时间
{
	int i, j;
	int flag;		//标记每层是否有人下
	int time;

	time = 0;
	for (i = 0; i <= highest; i++)	//计算每层花费时间
	{
		time += 6;
		flag = 0;
		for (j = 0; j < n; j++)		//计算每层每个人花费的时间
		{
			if (a[j] == i)
			{
				time += 1;
				flag = 1;
			}
		}
		if (flag)					//每层的开门时间
			time += 5;		
	}

	time += highest * 4;			//电梯下楼花费时间

	return time;
}

int main()
{
	int c, n, a[100], time;
	int i;
	int highest;	//要到的最高层

	scanf("%d", &c);

	while (c != 0)
	{
		time = 0;

		scanf("%d", &n);
		for (i = 0; i < n; i++)		//记录每个人要到的层数到a[i]
		{
			scanf("%d", &a[i]);
		}

		highest = max(a, n);

		time = count_time(n, a, highest);	//计算每组测试需要的总时间
		
		printf("%d\n", time-6);

		c--;
	}

	return 0;
}

 

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/8743678

posted in C/C++ 

我们先来看一下以下的声明:

int f(int);

int  (*pf)(int)=&f;//&操作符可选;因为函数名被使用时总是由编译器把它

                           //转换为函数指针;

int ans;

ans=f(25);

ans=(*pf)(25);

ans=pf(25);//间接访问操作并非必需,因为编译器需要的是一个函数指针;

**********************************************************************************

两个最常见的用途是把函数指针作为参数传递给函数以及用于转换表!

1.回调函数

这里有一个简单的函数,它用于在一个单链表中查找一个值,它的参数是一个指向

链表第一个节点的指针以及那个需要查找的值.

Node* search_list(Node* node,int const value)

{   while(node!=NULL)

  {    if(node->value==value)

                break;

       node=node->link;

   }

    return node;

}

       这个函数看上去相当简单,但它只适用于值为整数的链表,如果你需要在一个

字符串链表中查找,你不得不另外编写一个函数,这个函数和上面那个函数的绝大

部分代码相同,只是第二个参数的类型以及节点值的比较方法不同.

       一种更为通用的方法是查找函数与类型无关,这样它就能用于任何类型的值

的链表,我们必须对函数的两个方面进行修改,使它与类型无关.首先我们必须改变

比较的执行方式,这样函数就可以对任何类型的值进行比较.这个目标听上去好象

不可能,如果你编写语句用于比较整型值,它怎么还可能用于其他类型如字符串

的比较呢?解决方案就是使用函数指针,调用者编写一个函数,用于比较两个值,然后

把一个指向这个函数的指针作为参数传递给查找函数.然后查找函数调用这

个函数来执行值的比较,使用这种方法,任何类型的值都可以进行比较.

       我们必须修改的第二个方面是向函数传递一个指向值的指针而不是本身.

函数由一个void *形参,用于接收这个参数,然后指向这个值的指针便传递给比较

函数,这个修改使字符串和数组对象也可以被使用,字符串和数组无法作为参数传

递给函数,但指向它们的指针可以.

      使用这种技巧的函数叫"回调函数"(callback function);因为用户把一个函数指

针作为参数传递给其他函数,后者将"回调"用户的函数.任何时候,如果你所编写的

函数必须能够在不同的时刻执行不同类型的工作或执行只能由函数调用者定义

的工作,你都可以使用这个技巧.许多窗口系统使用回调函数连接多个动作,

如拖拽鼠标和点击按钮来指定用户程序中的某个特定函数.

      我们无法在这个上下文环境中为回调函数编写一个准确的原型,因为我们并

不知道进行比较的值的类型.事实上,我们需要查找函数能作用于任何类型的值,

解决这个难题的方法是把参数类型声明为"void *",表示"一个指向未知类型

的指针".

   

#include

#include "node.h"

Node* search_list(Node *node,void  const *value,

                  int(*compare)(void const*,void const*)) //函数声明;

{     while   (node!=NULL)

          {      if(compare(&node->value,value)==0)   break;

                  node=node->link;

           }

        return node;

}

      同时注意虽然函数不会修改参数node所指向的任何节点,但node并未声明

为const。如果node被声明为const,函数不得不返回一个const结果,这将限制

调用程序,它便无法修改查找函数所找到的节点。

      在一个特定的链表中进行查找时,用户需要编写一个适当的比较函数,并

把指向该函数的指针和指向需要查找的值的指针传递给查找函数。例如,下面

是一个比较函数,它用于在一个整数链表中进行查找。

int compare_ints(void const* a,void const* b)

{

         if(*(int*)a==*(int*)b)     return 0;

         else     return 1;

}

       这个函数将像下面这样使用:

desired_node=search_list(root,&desired_value,compare_ints);

2.转换表(jump table)

**   ** 转移表最好用个例子来解释。下面的代码段取自一个程序,它用于实现

一个袖珍式计算器。程序的其他部分已经读入两个数(op1和op2)和一个

操作符(oper)。下面的代码对操作符进行测试,最后决定调用哪个函数。

switch(oper)

{

case ADD:   result=add(op1,op2);break;

case SUB:    result=sub(op1,op2);break;

case MUL:    result=mul(op1,op2);break;

case DIV:     result=div(op1,op2);break;

......}

      对于一个新奇的具有上百个操作符的计算器,这条switch语句将会非常之长。

      为什么要调用函数来执行这些操作呢?把具体操作和选择操作的代码分开

是一种良好的设计方案。更为复杂的操作将肯定以独立的函数来实现,因为

它们的长度可能很长。但即使是简单的操作也可能具有副作用,例如保存一个

常量值用于以后的操作。

        为了使用switch语句,表示操作符的代码必须是整数。如果它们是从零开始

连续的整数,我们可以使用转换表来实现相同的任务。转换表就是一个函数指针

数组。

      创建一个转换表需要两个步骤。首先,声明并初始化一个函数指针数组。唯一

需要留心之处就是确保这些函数的原型出现在这个数组的声明之前。

double add(double,double);

double sub(double,double);

double mul(double,double);

double div(double,double);

……

double (*oper_func[])(double,double)={

add,sub,mul,div,

……};

      初始化列表中各个函数名的正确顺序取决于程序中用于表示每个操作符的

整型代码。这个例子假定ADD是0,SUB是1,MUL是2,接下去以此类推。

      第二个步骤是用下面这条语句替换前面整条switch语句!

result=oper_func[oper](op1,op2);

     oper从数组中选择正确的函数指针,而函数调用操作符将执行这个函数。

 

 

本文章迁移自http://blog.csdn.net/timberwolf_2012/article/details/8743628

/** * RECOMMENDED CONFIGURATION VARIABLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS. * LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables*/ /* var disqus_config = function () { this.page.url = PAGE_URL; // Replace PAGE_URL with your page's canonical URL variable this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page's unique identifier variable }; */ (function() { // DON'T EDIT BELOW THIS LINE var d = document, s = d.createElement('script'); s.src = 'https://chenzz.disqus.com/embed.js'; s.setAttribute('data-timestamp', +new Date()); (d.head || d.body).appendChild(s); })();