﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Cpp Fans</title><link>http://www.cppblog.com/threesh/</link><description /><language>zh-cn</language><lastBuildDate>Mon, 06 Apr 2026 03:30:38 GMT</lastBuildDate><pubDate>Mon, 06 Apr 2026 03:30:38 GMT</pubDate><ttl>60</ttl><item><title>[轉]七种武器——.NET工程师求职面试必杀技</title><link>http://www.cppblog.com/threesh/archive/2007/04/26/22884.html</link><dc:creator>Cpp Fans</dc:creator><author>Cpp Fans</author><pubDate>Thu, 26 Apr 2007 08:01:00 GMT</pubDate><guid>http://www.cppblog.com/threesh/archive/2007/04/26/22884.html</guid><wfw:comment>http://www.cppblog.com/threesh/comments/22884.html</wfw:comment><comments>http://www.cppblog.com/threesh/archive/2007/04/26/22884.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/threesh/comments/commentRss/22884.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/threesh/services/trackbacks/22884.html</trackback:ping><description><![CDATA[一、.NET框架（七种武器之孔雀翎） <br><br>开发人员应该熟悉.NET FrameWork体系结构和基本原理，熟悉CLR（公共语言运行时）和MSIL(中间语言)，熟悉.NET框架中的委托、线程、序列化、集合、垃圾回收机制、反射等内容。 <br><br>（世界上绝没有一种暗器能比孔雀翎更厉害，也绝没有一种武器能比孔雀翎更美丽&#8230;&#8230;孔雀翎娇小的身躯中隐藏着巨大的威力&#8230;&#8230;.NET框架的博大精深，正如同孔雀翎一样美丽而深不可测。） <br><br>二、面向对象软件开发（七种武器之霸王枪） <br><br>开发人员应该熟悉面向对象软件开发(OOP)基本概念，熟悉面向对象软件开发中的类、继承、封装、多态等概念，具备良好的面向对象软件开发思想和设计原则。 <br><br>（霸王，力拔山兮气盖世。枪，百兵之祖是为枪&#8230;&#8230;霸王枪是世上最霸道的兵器之一&#8230;&#8230;正如面向对象软件开发，它大小通吃，不论是采用何种软件开发框架，还是使用不同的开发语言，面向对象软件开发在其中畅通无阻，霸气十足。） <br><br>三、C# (七种武器之离别钩) <br><br>开发人员应该熟练掌握C#这门面向对象编程语言，虽然.NET框架支持多种编程语言，但C#无疑是最简洁、使用者最广泛和功能最强大的一种。 <br><br>（离别钩是一件武器，无论钩住人的任何部位，都能造成离别&#8230;&#8230;但使用它的初衷却是为了能够与所爱的人相聚&#8230;&#8230;C#是一门年轻的语言，它的出现，让更多的开发者爱上了C#，脱离了VB和ASP的阵营，造成离别。） <br><br>四、ASP.NET（七种武器之碧玉刀） <br><br>开发人员应该理解ASP.NET的页面生命周期、熟悉配置文件的格式、熟悉ASP.NET的各种服务器控件和数据控件、了解ASP.NET中的各种对象，了解ASP.NET2.0新特性。 <br><br>（刀是最容易上手的武器，也是使用最广泛的武器&#8230;&#8230;ASP.NET技术在网站开发当中的应用，正如同刀一样地使用频繁，更何况是一把华丽的碧玉刀。碧玉刀本身也是实力的象征，就如同ASP.NET在WEB开发中的位置。） <br><br>五、数据库(七种武器之长生剑) <br><br>开发人员需了解各种主流数据库，熟悉数据库的规范设计、精通SQL及存储过程、触发器的编写。 <br><br>（长生剑，世上最锋利的剑，剑气威力强大而又持续不断、绵绵不息&#8230;&#8230;正如同数据库一样，吸纳吞吐，化大象于无形，强力支撑着软件系统。要想在IT界获得长生，就看你数据库的功底了。） <br><br>六、AJAX技术(JAVASCRIPT和XML)(七种武器之多情环) <br><br>XML和JAVASCRIPT的跨平台特性，在实际软件开发中的运用越来越广泛，由于现代软件对用户界面和WEB前端的日益重视，集JAVASCRIPT和XML技术于大成的AJAX正在流行，特别是在基于WEB2.0的网站开发中。 <br><br>（多情环是一种奇特的武器。无论套住了什么，立刻就紧紧地缠住，绝不会再脱手，就像多情的恋人一样&#8230;&#8230;JAVASCRIPT和XML技术已经出现多年，此前一直不痛不痒，但由于集JAVASCRIPT和XML于大成的AJAX技术的出现及其在互联网上的不断应用，又重新焕发出生命活力，就像多情的环一样，将众多的开发者牢牢系住，在2006年红透了整个IT界，2007年AJAX技术将继续红火。） <br><br>七、软件体系架构(拳头) <br><br>优秀的软件离不开优秀的软件体系架构，作为开发人员，要想在IT行业更进一步，需要具备系统的、良好的软件体系架构思维，从而从更高层次决定软件的整体系统框架。 <br><br>（拳头也是一种武器。而且是无可替代的武器。当分散的五指握成拳头，它的力量又岂仅仅是原来的五倍&#8230;&#8230;优良的软件体系架构是整个软件开发体系的核心，就如同拳头一样，它是直接而致命的。但有一点，不是每个人的拳头都可以用做武器的。） <br><br>结束语：无论多可怕的武器，也比不上人类的信心。所以人类最厉害的武器。便是自己的信心。相信你自己，做最好的自己，你就会成功！ 
<img src ="http://www.cppblog.com/threesh/aggbug/22884.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/threesh/" target="_blank">Cpp Fans</a> 2007-04-26 16:01 <a href="http://www.cppblog.com/threesh/archive/2007/04/26/22884.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PL/SQL单行函数和组函数详解</title><link>http://www.cppblog.com/threesh/archive/2007/03/26/20595.html</link><dc:creator>Cpp Fans</dc:creator><author>Cpp Fans</author><pubDate>Mon, 26 Mar 2007 03:04:00 GMT</pubDate><guid>http://www.cppblog.com/threesh/archive/2007/03/26/20595.html</guid><wfw:comment>http://www.cppblog.com/threesh/comments/20595.html</wfw:comment><comments>http://www.cppblog.com/threesh/archive/2007/03/26/20595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/threesh/comments/commentRss/20595.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/threesh/services/trackbacks/20595.html</trackback:ping><description><![CDATA[
		<div class="cnt">
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">
				</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　函数是一种有零个或多个参数并且有一个返回值的程序。在SQL中Oracle内建了一系列函数，这些函数都可被称为SQL或PL/SQL语句，函数主要分为两大类：</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　 单行函数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　 组函数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　本文将讨论如何利用单行函数以及使用规则。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　SQL中的单行函数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　SQL和PL/SQL中自带很多类型的函数，有字符、数字、日期、转换、和混合型等多种函数用于处理单行数据，因此这些都可被统称为单行函数。这些函数均可用于SELECT,WHERE、ORDER BY等子句中，例如下面的例子中就包含了TO_CHAR,UPPER,SOUNDEX等单行函数。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">SELECT ename,TO_CHAR(hiredate,'day,DD-Mon-YYYY')FROM empWhere UPPER(ename) Like 'AL%'ORDER BY SOUNDEX(ename)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　单行函数也可以在其他语句中使用，如update的SET子句，INSERT的VALUES子句，DELET的WHERE子句,认证考试特别注意在SELECT语句中使用这些函数，所以我们的注意力也集中在SELECT语句中。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　NULL和单行函数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　在如何理解NULL上开始是很困难的，就算是一个很有经验的人依然对此感到困惑。NULL值表示一个未知数据或者一个空值，算术操作符的任何一个操作数为NULL值，结果均为提个NULL值,这个规则也适合很多函数，只有CONCAT,DECODE,DUMP,NVL,REPLACE在调用了 NULL参数时能够返回非NULL值。在这些中NVL函数时最重要的，因为他能直接处理NULL值，NVL有两个参数：NVL(x1,x2),x1和x2 都式表达式，当x1为null时返回X2,否则返回x1。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　下面我们看看emp数据表它包含了薪水、奖金两项，需要计算总的补偿</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">column name emp_id salary bonuskey type pk nulls/unique nn,u nnfk table datatype number number numberlength 11.2 11.2</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　不是简单的将薪水和奖金加起来就可以了，如果某一行是null值那么结果就将是null，比如下面的例子：</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">update empset salary=(salary+bonus)*1.1</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　这个语句中，雇员的工资和奖金都将更新为一个新的值，但是如果没有奖金，即 salary + null,那么就会得出错误的结论，这个时候就要使用nvl函数来排除null值的影响。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">所以正确的语句是：</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">update empset salary=(salary+nvl(bonus,0)*1.1</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">单行字符串函数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　单行字符串函数用于操作字符串数据，他们大多数有一个或多个参数，其中绝大多数返回字符串</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　ASCII()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c1是一字符串，返回c1第一个字母的ASCII码，他的逆函数是CHR()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">SELECT ASCII('A') BIG_A,ASCII('z') BIG_z FROM empBIG_A BIG_z65 122</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　CHR(＜i＞)[NCHAR_CS]</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　i是一个数字，函数返回十进制表示的字符</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select CHR(65),CHR(122),CHR(223) FROM empCHR65 CHR122 CHR223A z B</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　CONCAT(,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c1,c2均为字符串，函数将c2连接到c1的后面，如果c1为null,将返回c2.如果c2为null,则返回c1，如果c1、c2都为null，则返回null。他和操作符||返回的结果相同</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select concat('slobo ','Svoboda') username from dualusernameslobo Syoboda</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　INITCAP()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c1为一字符串。函数将每个单词的第一个字母大写其它字母小写返回。单词由空格，控制字符，标点符号限制。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select INITCAP('veni,vedi,vici') Ceasar from dualCeasarVeni,Vedi,Vici</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　INSTR(,[,＜i＞[,]])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c1,c2均为字符串，i,j为整数。函数返回c2在c1中第j次出现的位置，搜索从c1的第i个字符开始。当没有发现需要的字符时返回0,如果i为负数，那么搜索将从右到左进行，但是位置的计算还是从左到右，i和j的缺省值为1.</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select INSTR('Mississippi','i',3,3) from dualINSTR('MISSISSIPPI','I',3,3)11select INSTR('Mississippi','i',-2,3) from dualINSTR('MISSISSIPPI','I',3,3)2</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　INSTRB(,[,i[,j])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　与INSTR（）函数一样，只是他返回的是字节，对于单字节INSTRB()等于INSTR()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　LENGTH()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c1为字符串，返回c1的长度，如果c1为null，那么将返回null值。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select LENGTH('Ipso Facto') ergo from dualergo10</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　LENGTHb()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　与LENGTH()一样，返回字节。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　lower()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回c的小写字符，经常出现在where子串中</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select LOWER(colorname) from itemdetail WHERE LOWER(colorname) LIKE '%white%'COLORNAMEWinterwhite</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　LPAD(,＜i＞[,])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c1,c2均为字符串，i为整数。在c1的左侧用c2字符串补足致长度i,可多次重复，如果i小于c1的长度，那么只返回i那么长的c1字符，其他的将被截去。c2的缺省值为单空格，参见RPAD。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select LPAD(answer,7,'') padded,answer unpadded from question;PADDED UNPADDED Yes YesNO NOMaybe maybe</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　LTRIM(,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　把c1中最左边的字符去掉，使其第一个字符不在c2中，如果没有c2，那么c1就不会改变。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select LTRIM('Mississippi','Mis') from dualLTRppi</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　RPAD(,＜i＞[,])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　在c1的右侧用c2字符串补足致长度i,可多次重复，如果i小于c1的长度，那么只返回i那么长的c1字符，其他的将被截去。c2的缺省值为单空格,其他与LPAD相似</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　RTRIM(,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　把c1中最右边的字符去掉，使其第后一个字符不在c2中，如果没有c2，那么c1就不会改变。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　REPLACE(,[,])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c1,c2,c3都是字符串，函数用c3代替出现在c1中的c2后返回。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select REPLACE('uptown','up','down') from dualREPLACEdowntown</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　STBSTR(,＜i＞[,])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c1为一字符串，i,j为整数，从c1的第i位开始返回长度为j的子字符串，如果j为空，则直到串的尾部。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select SUBSTR('Message',1,4) from dualSUBSMess</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　SUBSTRB(,＜i＞[,])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　与SUBSTR大致相同，只是I,J是以字节计算。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　SOUNDEX()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回与c1发音相似的词</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select SOUNDEX('dawes') Dawes SOUNDEX('daws') Daws, SOUNDEX('dawson') from dualDawes Daws DawsonD200 D200 D250</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　TRANSLATE(,,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　将c1中与c2相同的字符以c3代替</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select TRANSLATE('fumble','uf','ar') test from dualTEXTramble</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　TRIM([[]] from c3)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　将c3串中的第一个，最后一个，或者都删除。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select TRIM(' space padded ') trim from dual TRIMspace padded</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　UPPER()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回c1的大写，常出现where子串中</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select name from dual where UPPER(name) LIKE 'KI%'NAMEKING</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">单行数字函数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　单行数字函数操作数字数据，执行数学和算术运算。所有函数都有数字参数并返回数字值。所有三角函数的操作数和值都是弧度而不是角度，oracle没有提供内建的弧度和角度的转换函数。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　ABS()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回n的绝对值</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　ACOS()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　反余玄函数，返回-1到1之间的数。n表示弧度</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select ACOS(-1) pi,ACOS(1) ZERO FROM dualPI ZERO3.14159265 0</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　ASIN()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　反正玄函数，返回-1到1，n表示弧度</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　ATAN()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　反正切函数，返回n的反正切值，n表示弧度。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　CEIL()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回大于或等于n的最小整数。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　COS()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回n的余玄值，n为弧度</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　COSH()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回n的双曲余玄值，n 为数字。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select COSH(&lt;1.4&gt;) FROM dualCOSH(1.4)2.15089847</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　EXP()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回e的n次幂，e=2.71828183.</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　FLOOR()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回小于等于N的最大整数。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　LN()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回N的自然对数，N必须大于0</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　LOG(,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回以n1为底n2的对数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　MOD()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回n1除以n2的余数，</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　POWER(,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回n1的n2次方</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　ROUND(,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回舍入小数点右边n2位的n1的值，n2的缺省值为0，这回将小数点最接近的整数，如果n2为负数就舍入到小数点左边相应的位上，n2必须是整数。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select ROUND(12345,-2),ROUND(12345.54321,2) FROM dualROUND(12345,-2) ROUND(12345.54321,2)12300 12345.54</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　SIGN()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　如果n为负数，返回-1,如果n为正数，返回1，如果n=0返回0.</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　SIN（)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回n的正玄值,n为弧度。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　SINH()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回n的双曲正玄值,n为弧度。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　SQRT()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回n的平方根,n为弧度</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　TAN（)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回n的正切值,n为弧度</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　TANH()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回n的双曲正切值,n为弧度</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　TRUNC(,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回截尾到n2位小数的n1的值，n2缺省设置为0，当n2为缺省设置时会将n1截尾为整数，如果n2为负值，就截尾在小数点左边相应的位上。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　单行日期函数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　单行日期函数操作DATA数据类型，绝大多数都有DATA数据类型的参数，绝大多数返回的也是DATA数据类型的值。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　ADD_MONTHS(,＜i＞)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回日期d加上i个月后的结果。i可以使任意整数。如果i是一个小数，那么数据库将隐式的他转换成整数，将会截去小数点后面的部分。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　LAST_DAY()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　函数返回包含日期d的月份的最后一天</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　MONTHS_BETWEEN(,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回d1和d2之间月的数目,如果d1和d2的日的日期都相同，或者都使该月的最后一天，那么将返回一个整数，否则会返回的结果将包含一个分数。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　NEW_TIME(,,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　d1是一个日期数据类型，当时区tz1中的日期和时间是d时，返回时区tz2中的日期和时间。tz1和tz2时字符串。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　NEXT_DAY(,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回日期d后由dow给出的条件的第一天，dow使用当前会话中给出的语言指定了一周中的某一天，返回的时间分量与d的时间分量相同。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select NEXT_DAY('01-Jan-2000','Monday') "1st Monday",NEXT_DAY('01-Nov-2004','Tuesday')+7 "2nd Tuesday") from dual;1st Monday 2nd Tuesday03-Jan-2000 09-Nov-2004</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　ROUND([,])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　将日期d按照fmt指定的格式舍入，fmt为字符串。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　SYADATE</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　函数没有参数，返回当前日期和时间。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　TRUNC([,])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回由fmt指定的单位的日期d.</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">单行转换函数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　单行转换函数用于操作多数据类型，在数据类型之间进行转换。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　CHARTORWID()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c 使一个字符串，函数将c转换为RWID数据类型。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">SELECT test_id from test_case where rowid=CHARTORWID('AAAA0SAACAAAALiAAA')</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　CONVERT(,[,])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c尾字符串，dset、sset是两个字符集，函数将字符串c由sset字符集转换为dset字符集，sset的缺省设置为数据库的字符集。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　HEXTORAW()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　x为16进制的字符串，函数将16进制的x转换为RAW数据类型。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　RAWTOHEX()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　x是RAW数据类型字符串，函数将RAW数据类转换为16进制的数据类型。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　ROWIDTOCHAR()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　函数将ROWID数据类型转换为CHAR数据类型。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　TO_CHAR([[,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　x是一个data或number数据类型，函数将x转换成fmt指定格式的char数据类型，如果x为日期nlsparm=NLS_DATE_LANGUAGE 控制返回的月份和日份所使用的语言。如果x为数字nlsparm=NLS_NUMERIC_CHARACTERS 用来指定小数位和千分位的分隔符，以及货币符号。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">NLS_NUMERIC_CHARACTERS ="dg", NLS_CURRENCY="string"</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　TO_DATE([,[,）</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c表示字符串，fmt表示一种特殊格式的字符串。返回按照fmt格式显示的c,nlsparm表示使用的语言。函数将字符串c转换成date数据类型。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　TO_MULTI_BYTE()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c表示一个字符串，函数将c的担子截字符转换成多字节字符。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　TO_NUMBER([,[,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　c表示字符串，fmt表示一个特殊格式的字符串，函数返回值按照fmt指定的格式显示。nlsparm表示语言，函数将返回c代表的数字。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　TO_SINGLE_BYTE()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　将字符串c中得多字节字符转化成等价的单字节字符。该函数仅当数据库字符集同时包含单字节和多字节字符时才使用</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　其它单行函数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　BFILENAME(</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">,)</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　dir是一个directory类型的对象，file为一文件名。函数返回一个空的BFILE位置值指示符，函数用于初始化BFILE变量或者是BFILE列。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　DECODE(,,[,,,[])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　x是一个表达式，m1是一个匹配表达式，x与m1比较，如果m1等于x，那么返回r1,否则,x与m2比较，依次类推m3,m4,m5....直到有返回结果。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　DUMP(,[,[,[,]]])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　x是一个表达式或字符，fmt表示8进制、10进制、16进制、或则单字符。函数返回包含了有关x的内部表示信息的VARCHAR2类型的值。如果指定了n1,n2那么从n1开始的长度为n2的字节将被返回。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　EMPTY_BLOB()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　该函数没有参数，函数返回 一个空的BLOB位置指示符。函数用于初始化一个BLOB变量或BLOB列。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　EMPTY_CLOB()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　该函数没有参数，函数返回 一个空的CLOB位置指示符。函数用于初始化一个CLOB变量或CLOB列。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　GREATEST()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　exp_list是一列表达式，返回其中最大的表达式，每个表达式都被隐含的转换第一个表达式的数据类型，如果第一个表达式是字符串数据类型中的任何一个，那么返回的结果是varchar2数据类型，同时使用的比较是非填充空格类型的比较。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　LEAST()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　exp_list是一列表达式，返回其中最小的表达式，每个表达式都被隐含的转换第一个表达式的数据类型，如果第一个表达式是字符串数据类型中的任何一个，将返回的结果是varchar2数据类型，同时使用的比较是非填充空格类型的比较。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　UID</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　该函数没有参数，返回唯一标示当前数据库用户的整数。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　USER</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回当前用户的用户名</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　USERENV()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　基于opt返回包含当前会话信息。opt的可选值为：</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　ISDBA　 　　会话中SYSDBA脚色响应，返回TRUE</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　SESSIONID 　返回审计会话标示符ENTRYID 　　返回可用的审计项标示符</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　INSTANCE　　在会话连接后，返回实例标示符。该值只用于运行Parallel 服务器并且有 多个实例的情况下使用。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　LANGUAGE　　返回语言、地域、数据库设置的字符集。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　LANG　　　　返回语言名称的ISO缩写。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　TERMINAL　　为当前会话使用的终端或计算机返回操作系统的标示符。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　VSIZE()</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　x是一个表达式。返回x内部表示的字节数。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">SQL中的组函数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　组函数也叫集合函数，返回基于多个行的单一结果，行的准确数量无法确定，除非查询被执行并且所有的结果都被包含在内。与单行函数不同的是，在解析时所有的行都是已知的。由于这种差别使组函数与单行函数有在要求和行为上有微小的差异.</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　组（多行）函数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　与单行函数相比，oracle提供了丰富的基于组的，多行的函数。这些函数可以在select或select的having子句中使用，当用于select子串时常常都和GROUP BY一起使用。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　AVG([{DISYINCT|ALL}])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回数值的平均值。缺省设置为ALL.</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">SELECT AVG(sal),AVG(ALL sal),AVG(DISTINCT sal) FROM scott.empAVG(SAL) AVG(ALL SAL) AVG(DISTINCT SAL)1877.94118 1877.94118 1916.071413</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　COUNT({*|DISTINCT|ALL} )</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回查询中行的数目，缺省设置是ALL,*表示返回所有的行。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　MAX([{DISTINCT|ALL}])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回选择列表项目的最大值，如果x是字符串数据类型，他返回一个VARCHAR2数据类型，如果X是一个DATA数据类型，返回一个日期，如果X是numeric数据类型，返回一个数字。注意distinct和all不起作用，应为最大值与这两种设置是相同的。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　MIN([{DISTINCT|ALL}])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回选择列表项目的最小值。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　STDDEV([{DISTINCT|ALL}])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回选者的列表项目的标准差，所谓标准差是方差的平方根。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　SUM([{DISTINCT|ALL}])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回选择列表项目的数值的总和。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　VARIANCE([{DISTINCT|ALL}])</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　返回选择列表项目的统计方差。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　用GROUP BY给数据分组</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　正如题目暗示的那样组函数就是操作那些已经分好组的数据，我们告诉数据库用GROUP BY怎样给数据分组或者分类，当我们在SELECT语句的SELECT子句中使用组函数时，我们必须把为分组或非常数列放置在GROUP BY子句中，如果没有用group by进行专门处理，那么缺省的分类是将整个结果设为一类。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select stat,counter(*) zip_count from zip_codes GROUP BY state;ST ZIP_COUNT-- ---------AK 360AL 1212AR 1309AZ 768CA 3982</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　在这个例子中，我们用state字段分类；如果我们要将结果按照zip_codes排序,可以用ORDER BY语句，ORDER BY子句可以使用列或组函数。</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">select stat,counter(*) zip_count from zip_codes GROUP BY state ORDER BY COUNT(*) DESC;ST COUNT(*)-- --------NY 4312PA 4297TX 4123CA 3982</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　用HAVING子句限制分组数据</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　现在你已经知道了在查询的SELECT语句和ORDER BY子句中使用主函数，组函数只能用于两个子串中，组函数不能用于WHERE子串中，例如下面的查询是错误的：</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">错误SELECT sales_clerk,SUN(sale_amount) FROM gross_sales WHERE sales_dept='OUTSIDE' AND SUM(sale_amount)&gt;10000 GROUP BY sales_clerk</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　这个语句中数据库不知道SUM()是什么，当我们需要指示数据库对行分组，然后限制分组后的行的输出时，正确的方法是使用HAVING语句：</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">SELECT sales_clerk,SUN(sale_amount) FROM gross_sales WHERE sales_dept='OUTSIDE' GROUP BY sales_clerkHAVING SUM(sale_amount)&gt;10000;</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　嵌套函数</p>
				<p style="FONT-SIZE: 9pt; MARGIN: 0in">　　函数可以嵌套。一个函数的输出可以是另一个函数的输入。操作数有一个可继承的执行过程。但函数的优先权只是基于位置，函数遵循由内到外，由左到右的原则。嵌套技术一般用于象DECODE这样的能被用于逻辑判断语句IF....THEN...ELSE的函数。 </p>
		</div>
<img src ="http://www.cppblog.com/threesh/aggbug/20595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/threesh/" target="_blank">Cpp Fans</a> 2007-03-26 11:04 <a href="http://www.cppblog.com/threesh/archive/2007/03/26/20595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]学习C++的一点体会</title><link>http://www.cppblog.com/threesh/archive/2007/01/28/18104.html</link><dc:creator>Cpp Fans</dc:creator><author>Cpp Fans</author><pubDate>Sat, 27 Jan 2007 16:52:00 GMT</pubDate><guid>http://www.cppblog.com/threesh/archive/2007/01/28/18104.html</guid><wfw:comment>http://www.cppblog.com/threesh/comments/18104.html</wfw:comment><comments>http://www.cppblog.com/threesh/archive/2007/01/28/18104.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/threesh/comments/commentRss/18104.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/threesh/services/trackbacks/18104.html</trackback:ping><description><![CDATA[
		<p>我从去年11月份开始自学C++（本人现在做C#开发），现在把我这10来个月学习体会写出来和大家分享。</p>
		<p>1。关于要不要学习C++？（结论：要学，一定要学！）<br />如今在网上很多为要不要学C++争的不可开交，因为现在JAVA，C#，。NET都炒的很火，特别是JAVA，大有炸平庐山，停止地球转动之势。用林锐同志的话说，其实JAVA只是C++外甥，跑到舅舅身上撒了一泡尿而已。首先，我们从JAVA 的来历上来说，JAVA的设计初衷是用来给家用电器设计程序使用的，最初设计者想用C++，但觉得C++太复杂，就在C++的基础上做了一些简化，设计出了JAVA，它的设计思想是跨平台，所以必须先在运行平台上安装虚拟机，然后把源程序编译成中间语言在运行。这是一个优点，但我们说任意优点都是建立在缺点上的，JAVA的缺点就是运行速度慢，这对于某些系统来说是致命弱点。况且，JAVA中没有指针，对于制作系统软件来说，这更是无法饶恕的。再来看C++。C++产生于美国贝尔实验室，就是发明电话那个公司。设计初衷是用来改进C的开发效率，C是面向过程的语言，开发效率底，贝尔实验室有大量的C程序员，所以只要在开发效率上提高一点点，就可以节约数目庞大的成本。C是什么东西？是用来代替汇编编写操作系统的语言，用C++代替C，可以得出两个结论：第一，C++必须具有同C相当的执行速度；第二，C++必须比C具有较高的开发效率。执行速度方面，C++的设计者的思想就是在改进开发效率的同时尽量不增加C++的系统开销，当然有些地方非增加开销不可，也把开销控制在最小程度内。具非权威研究报告，C++比C的执行开销多出不到10%。开发效率方面，C++引进了面向对象机制，库机制，最大程度上实现了代码重用，这是软件开发人员的福音。C++在改进C的开发效率的同时，对C的缺陷做了一些修补。C的优点在C++中都得到了很好的保留，C的缺点在C++中都有了改进，有了更好的解决办法。而且，为了现有的大量C程序维护，C++还全面兼容了C。纵观当今程序语言家族，我觉得只有C可以C++相提并论，门当户对，其它语言都无法和C++相提并论。无论从什么角度来说，C++都算的上语言中的老大。<br />如今，网上有很多关于C++的争论，其实争论的人都是一些不知情的人，绝大多数是学校里的学生，我也曾经这样。在学校里的时候，不知道究竟应该学习什么，要是遇到好的老师还可以，遇到垃圾老师，垃圾学校那就更糟糕。如今，什么MCSE，CCNA，CIW等等认证漫天飞，把人搞的昏头昏脑，其实这都是认证公司炒的。社会上需要的是有真才实学的人，而不是需要证书。<br />我从大二开始学习编程，一开始学习VB，后来学习DELPHI，再后来学习C#，再后来学习C++，绕了个大圈子，最后还是绕回来了。而且重新学习数据结构，操作系统，学习软件工程，学习大学本科的基本课程，重新读外国的程序设计名著，而这些以前在大学是不屑一顾的。劝如今还在学校的师弟师妹们，努力学习C++。</p>
		<p>2。为什么要学习学习C++<br />1）C++的程序员身价普遍较高，当然，前提是你必须是高手。我所在的城市，那些公司根本就招不到合格的C++程序员，一方面C++程序员要求高，学习C++的人越来越少了。当然，怀着这个目的，你或许永远无法成为C++高手，但我把这个原因放在最前面，可以给大家一个很明确的激励，当你接触C++后，发现从学习中获得乐趣比高的工资更有动力；<br />2）C++的优势是用来开发大型软件，从中可以学到很多优秀的软件设计思想。C++不是软件开发的首选工具，一般说来，大多人更愿意学习和使用VB，为什么，简单。简单的另一个方面是功能的局限。微软公司恨不的所有人都学VB，只有他一家会C++。容易上手，大家都喜欢学，喜欢用，很多人拿一本200页的书，看个两三个星期，就觉得自己是个程序员了，可以开发软件了，而且觉得做出来的东西很不错。当软件规模大到一定程度的时候，其他语言就越来越无法驾驭，这时C++的优势就体现出来了。你说做个成绩管理系统，人事查询系统，用VB，DELPHI，C#，JAVA都行，但是例如银行，电信，保险，操作系统，数据仓库，图形处理，编译系统，较底层的软件时，其他工具几乎是无法完成的。就说C++的指针，JAVA没有，在遇到数据量交大的数据排序，搜索，动态内存分配时，它就没有办法了。所以说，学习C++，不仅仅是学到的一种语言，还学习了优秀的软件设计思想。<br />3）学习C++可以学习到计算机底层的理论，即使不是用C++开发，对计算机运行机制的理解，对建制稳定的系统，对运用其他语言，也是一种促进。这一点，我是在学习过程中体会到的，所以，要说出个大家可以接受的理由来较难，大家以后学习就知道了。</p>
		<p>3。怎样学习C++？<br />首先，我们必须承认，学习要讲究方法，有捷径。其次，我们还得承认，学习要下苦功，要务实。上小学的时候，书上有个故事，是关于王羲之学习书法的：王献之问他父亲王羲之，学习书法的秘诀是什么，他父亲把他带到后院，指着18口大水缸说，你如果把这里的水都写完了，就知道书法的秘诀在那里了。这个故事相信很多人都还记得。前几天看梁肇新（豪杰公司老板）的《高手箴言》，他说如果你如果愿意利用5年时间来成为高手，那么你只要两三年就会成为高手，如果你想一年成为高手，那么你5年也成不了高手。学习要切忌浮躁，要脚踏实地。我曾经很浮躁，结果一直呆在菜鸟堆里，当半年前我静下心来学习C++，才感觉有真正的进步。现在做WEB开发，虽然我从来不看WEB开发的书，但是我的同事遇到问题时，我经常能一下说出问题的所在。因为你看问题的角度变了。所以，学习C++的第一个方法是：切忌浮躁。其实学任何东西都一样，欲速则不达。从基本数据类型看起，从基本流程控制语句写起。<br />其次，教材很重要，要看经典名著。<br /><br />其次，教材很重要，要看经典名著，而且如果英语好，最好看原版英文教材。<br />经典之所以成为经典，是因为经历了考验沉淀下来的东西。去年9月份，当我打算转向C++的时候，曾向我一位同事咨询，他向我推荐了《C++编程思想》，还说叫我一定要读。当我读完前面三到四章的时候，就发觉自己找到了感觉。接下来，我一口气读完了整本书，当然其中很多东西还是无法真正理解，这是一本很深邃的书。废话少说，我现在把我自己看过的C++参考书籍列出来：</p>
		<p>1）《C++入门经典》，原名《The C++ Language Begeining》,作者Ivor Horton 此书浅显易懂极适合入门，书中包括最基本的程序设计知识，例如基本数据类型，流程控制语句，函数设计。即使没有任何程序设计基础的人，看着也不觉得累。书中一些很有特色的事例，能促进和加深读者的理解。但此书的代码风格实在有些糟糕。</p>
		<p>2）《C++编程思想》,原名《Thinking in C++》,作者Bruce Eckell, 此书的名气就不在这里说了.此书最新版本(第三版)开头部分增加了几章讲C语言的部分,然后把读者逐渐引向C++,在讨论语言的一个特性时,往往总是先讲解在C中的解决方法,然后讨论这中方法的局限和不足之处,再讨论C++中的解决方法.据我的感受,此书作者的初衷是引导C程序员走向C++,但后来发现大多数新生代程序员,非美国的程序员不一定懂C,于是就在第三版中加入了介绍C的部分. 此书最大的特点是, 作者善于透过语言现象,看看屏风后面究竟发生了什么(例如,显示出生成的汇编语言).消化好这本书，C++水平上一个大台阶；</p>
		<p>3）《C++高效编程》，原名《Effect C++》。此书重点探讨C++的一些技术死角，我只看过其中很少的一些章节，在此不作过多评论；</p>
		<p>4）《C++ Primer》，作者Stanley B.Lippman，此书还没有读过，接下来读这本书。我在网上找了一点对此书特点的描述：对C++基本概念和技术全面而且权威的阐述，对现代C++编程风格的强调，使本书成为C++初学者的最佳指南；对于中高级程序员，本书也是不可或缺的参考书。第4版不再强调低层编程技术，而把中心转向标准库的使用。书中很早就开始介绍标准库，示例也已经重新改写，充分利用了标准库设施。我们也对语言主题叙述的先后次序进行了重新编排，使讲解更加流畅；</p>
		<p>5）《C++编程语言》，原名《C++ Program Language》，作者乃C++的发明者被誉为C++之父的Bjarne Stroustrup，此书我只读了一部分，说实话，有些难。此书的作者就是C++的创始人，发明者，知识非常渊博，其思想深度远远在前面几位之上。如果你想知道C++究竟能做什么，C++那些希奇古怪的特性为什么那样设计，那你就去参考这本书。另外，阅读此书时，你还会为作者那种深邃的思想，博大的胸怀感觉到一种发自内的快乐，舒畅。书中还讲到了很多大型系统设计的方法和技巧。总之，不读此书，是作为程序员的一大遗憾。我建议先阅读《C++编程思想》，再参考此书。因为《C++编程思想》的作者说，他写这本书的目的就是为了大家能够参考《C++编程语言》这本书；</p>
		<p>6）《C++高质量编程》，作者林锐。此书不属于经典名著，但我也比较推荐这本书。作者不象国内其他作者那样迂腐功利，而是从一个程序员的角度，介绍他在以往开发过程中遇到的问题和积累的经验，这本书很薄，但其中的思想方法很有用。且语句诙谐幽默，阅读起来很轻松；</p>
		<p>任何一本书，都有他的可取之处；任何一本书，都无法解决在学习中遇到的所有问题；任何一本书，都无法替代人的智慧和经验。但是好的教材，可以起到好的指导效果，可以使学习少走弯路。但我不怎么建议看比较薄（600页以下）的书，因为对于C++来说，这样的篇幅根本就说不清楚，也不建议看国内作者的教材，你发现大多是从上面所说的书中抄下来的。</p>
		<p>4。C++和VC的区别<br />目前我们所说的C++，通常意义上指标准C++，就是美国C++标准委员会发布的C++。它定义了一些基本的语言规范语言特性，定义了一个框架，还有一个标准库。虽然产生于UNIX下，但它不属于某一个平台，某一个厂商，某一个编译器。它是一种统称，一种概念。VC是微软公司在WINDOWS平台下的一种开发工具，本质上和VB，C#没有什么区别，只是较之底层一些。VC支持标准C++，但不百分之百支持。一般来说，学习C++可以使用VC的编译环境，但是必须要使用标准库。还有其他一些C++编译器例如C++ BUIDER，就是Borland公司生产的WINDOWS下的C++编译器，GCC是LINUX下的常用的C++编译器。估计在苹果机下也有相应的C++编译器，因为C++处理图形系统是其特长。</p>
		<p>要学习C++，就不要从VC学起，学习VC无法学到真正的C++编程思想，而你只是学会了使用类库而已。C++的特性是什么？C++本质是什么？C++的精华是什么？我觉得总结成一句话：利用面向对象的思想，解决大型系统的开发问题。</p>
		<p>5。学习C++的重点<br />如果你学习过C或者了解C，那么在学习C++的时候更容易受C的影响，记住，C是面向过程的语，C++是面向对象的语言。如果你学习过C，那么学习C++的重点是掌握C++的新特性，C与C++的区别，C++的面向对象特性，尝试用C++的风格去编写程序，用C++的技术去解决问题。或许你认为C很不错，但在C++可能有更好的解决办法；</p>
		<p>如果你学习过JAVA，C#或DELPHI，那么你应该对面向对象机制很熟悉。但是，C++中的面向对象机制和上述几种语言有所区别，例如多重继承。最好尝试在没有用户界面的环境下编写程序，还有，指针是C++的精华之一，所以必须掌握；</p>
		<p>如果你没有编程基础，那就直接从C++学起，这样就没有其他语言的干扰和影响。祝贺你，一开始就接触了这样一种伟大的语言；</p>
		<p>我觉得，C++的重点可以用三个词来描述：指针，面向对象，标准库。</p>
		<p>最后，在这里同所有学习C++的程序员共勉，不要担心学习C++会被淘汰，我所在的单位还有大量的Informix程序员，而且日子过的很舒服。我小时候学书法，老师常对我说一句话就是：字写的好，哪怕拿一根筷子在嘴巴里咬几下，都写的好看，而不在于用什么笔。用C++之父Bjarne Stroustrup的话来说：只要你在使用电脑，你就直接或间接使用了C++。</p>
		<p>让我们共同学习，共同进步，相互交流，相互促进。</p>
<img src ="http://www.cppblog.com/threesh/aggbug/18104.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/threesh/" target="_blank">Cpp Fans</a> 2007-01-28 00:52 <a href="http://www.cppblog.com/threesh/archive/2007/01/28/18104.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个研究生毕业以后的人生规划 </title><link>http://www.cppblog.com/threesh/archive/2006/12/26/16875.html</link><dc:creator>Cpp Fans</dc:creator><author>Cpp Fans</author><pubDate>Tue, 26 Dec 2006 08:51:00 GMT</pubDate><guid>http://www.cppblog.com/threesh/archive/2006/12/26/16875.html</guid><wfw:comment>http://www.cppblog.com/threesh/comments/16875.html</wfw:comment><comments>http://www.cppblog.com/threesh/archive/2006/12/26/16875.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/threesh/comments/commentRss/16875.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/threesh/services/trackbacks/16875.html</trackback:ping><description><![CDATA[
		<font size="2">
				<strong>一个研究生毕业以后的人生规划（转自天涯虚拟社区）<br /><br /></strong>我今年39岁了， 25岁研究生毕业，工作14年，回头看看，应该说走了不少的弯路 <br />，有一些 <br /><br />经验和教训。现在开一个小公司，赚的钱刚够养家糊口的。看看这些刚毕业的学生，对前 <br />景也很迷茫，想抛砖引玉，谈谈自己的看法，局限于理工科的学生，我对文科的不懂，身 <br />边的朋友也没有这一类型的。 <br /><br />　　91年研究生毕业，那时出路就是1种：留在北京的国营单位，搞一个北京户口，这是最 <br />好的选择。到后来的2～3年内，户口落定了，又分成4条出路： <br /><br />　　1、 上国内的大企业，如：华为 <br /><br />　　2、 自己做公司，做产品开发； <br /><br />　　3、 上外企，比如：爱立信、诺基亚 <br /><br />　　4、 自己做公司，做买卖； <br /><br />　　5、 移民加拿大 <br /><br />　　我想，首先要看自己适合做什么？做技术还是做买卖。 <br /><br />　　做技术，需要你对技术感兴趣。我掰着数了一遍，我们研究生班的30来号人，实际上 <br />，适合做技术的，大概只有3、4个人，这几个人，1个现在还在华为，3个移民加拿大了， <br />现在这4个人混的还可以，在华为的同学也移民加拿大了，他在华为呆了6年，在华为奖金 <br />工资加起来大概30万吧，还有华为的股票，再过几年，华为的股票一上市，也能值个100～ <br />200万。要是一毕业就去华为，那现在就绝对不是这个数字了。 <br /><br />　　要是做技术，最好的就是上大公司，国内的大型企业，象华为中兴肯定是首选，能学 <br />到很多东西。华为虽然累，但是，年轻人不能怕累，要是到老了，还需要去打拼，那才是 <br />真的累啊。 <br /><br />　　在外企，我想他们主要就是技术支持和销售，但是技术是学不到的，当然不能一概而 <br />论，我指的是象爱立信和诺基亚，真正的研发不会在中国做的，学到的也不如在华为多， <br />其它的中兴我不是很了解，我想应该也不错啊。 <br /><br />一个人都有一技之长，有傍身之技，那是最好的，走到哪里，都能有一口饭吃，还吃的不 <br />错，这是传统的观点。 <br /><br />　　任何技术都是要在某个行业去应用，这个行业市场越大当然越好；要在一个领域之内 <br />，做深做精，成为绝对的专家，这是走技术道路的人的选择。不要跳来跳去，在中国，再 <br />小的行业你要做精深了，都可以产生很大的利润。 <br /><br />　　研究生刚毕业的时候，做产品开发的有不少人，都是自己拍拍脑子，觉得这个产品有 <br />市场，就自己出来做。现在看来，我的这些同学，做产品开发的成功的没有一例，为什么 <br />？资源不足。 <br /><br />　　1． 资金，刚毕业的学生啊，就是没钱；没钱，也意味着你开发的东西都是小产品； <br />而且只能哥几个自己上，研发、生产、销售都是一个人或者几个人自己来，没有积累，什 <br />么都是重新来过。 <br /><br />　　2． 人脉，任何一个行业，要想进去，需要有很深的人脉，否则，谁会用你的东西啊 <br />？谁敢用你的东西啊？ <br /><br />　　我看到的，我这个班上开发产品的，自己还在坚持的，只剩下一个人了，说实在的， <br />到现在，没有自己的汽车，也没有自己的房子，混的挺惨的。现在出国的不说了，在外企 <br />、在华为，至少都是几十万的年薪了，还有各种福利，就是产品开发成功了，又能如何？ <br />也就是这样了，但是以前那些年，都没有金钱的积累，等于白干。 <br /><br />　　我身边的一个自动化系的研究生班的同学，能靠自己开发产品活得还可以的，也只有 <br />2个人。说明这条路不是那么好走的啊。 <br /><br />　　其次就是上外企。我的2个同学，一个上了爱立信，一个先到爱立信后到诺基亚，都混 <br />的不错。到诺基亚的后来利用在诺基亚结识的人脉（就是哪些电信的头头脑脑），自己开 <br />了公司，也赚了不少的钱。 <br /><br />　　外企最大的好处就是除了能学到比较规范的管理外，还能给你的职业生涯镀金。到了 <br />一个外企外，再到同行业的外企我想就很容易了。而且外企的收入高啊。 <br /><br />　　自己做公司，做买卖，一开始有3～4个人走这条路，但是真正发财的只有一个人，其 <br />他人后来上外企了。做买卖，还是要有一定的天赋，还有机遇。要有对金钱的赤裸裸的欲 <br />望，要有商业上的头脑。后来我们同学在一起谈，说，我们即使给自己这个机遇，也未必 <br />能做的好。何况当时那个同学看好的产品（做一个台湾产品的代理），我们大家都没有看 <br />好，说明，真理还是掌握在少数人手里。 <br /><br />　　到后来，同学们纷纷移民移民加拿大。 <br /><br />　　移民加拿大对搞技术的人来说，还是一个不错的选择，但是要尽早，练了几年的技术 <br />，就赶紧出去，大概是在1996年走了不到10个，现在都还可以，买了房子和车了。要是晚 <br />了，语言再学也难了，而且在国内都混的还可以了，也就没有必要出去了。 <br /><br />我自己呢，先是在国营的研究所混了4年，后来到一家公司干了6年，2002年出来自己做公 <br />司，现在也就是混了一个温饱吧，算是有房有车，有点积蓄，但是不多，还有一个可爱的 <br />女儿。回首这10来年，有一些经验和教训。 <br /><br />　　1． 要有一个职业生涯的规划。首先需要定位自己做什么合适，是做买卖还是做技术 <br />，一条路走到黑；当然，做了技术，后来改行也行； <br /><br />　　2． 做技术，就是要做精做深，成为这个行业的这个技术的专家；最好就是去国内的 <br />大公司，才能全面学到东西，能够给你培训的机会；如果大公司进不去，先到小公司练技 <br />术，找机会再到大公司去镀金，学高深的技术。千万不要自己做产品，要做也是对这个行 <br />业熟悉了，再去做。 <br /><br />　　3． 积极争取机会。积极争取学习和进步的机会。比如，做技术，就需要多锻炼，多 <br />学习，来提高自己的水平。一门技术，只要有机会去学习，都能学的会；要是没有机会， <br />天才也没有办法学到这个技术。柳传志就说，杨元庆就是“哭着喊着要进步”，实际上， <br />就是争取自己的机会；当然，这种强烈的进步欲望，也是领导看重的地方。每一步都走在 <br />前面，积累10年，你就有了比其他人更多的机会了。 <br /><br />　　4． 积累个人的信誉。从你的职业生涯的第一天，就要按照诚信的原则办事。要做到 <br />，当人们提起你的名字的时候，说，这哥们还不错，做事还行。 <br /><br />　　5． 注意利用资源。如果你有有钱的亲戚、成功的长辈或者朋友，可以充分利用这些 <br />机会，得到更加顺利的发展前景。 <br /><br />　　6． 注意财富的不断积累。人生要想得到自由，财富是很关键的。否则，永远仰人鼻 <br />息，永远看人脸色。人都是势利眼。今后的家庭、职业生涯，金钱的积累很重要，没有钱 <br />，永远不能开张自己的事业，得到更多的机会；财富要做到逐年积累，你才能家庭生活幸 <br />福。没有钱是不可能有幸福的家庭的。 <br /><br />　　7． 注意人脉的积累。最终，事业要靠在社会上的人脉的资源。要注意认识在你这个 <br />行业的人，结交他们，最终他们会成为你事业上的助力。 <br /><br />　　8． 寻求贵人相助。要找大老板来帮助你，得到大老板的赏识。想想看，大蛋糕，切 <br />一点就够了，小蛋糕，都给你也吃不饱啊。 <br /><br />　　9． 多听听成功的前辈和成功的朋友的意见。注意少听家里长辈的意见，尤其是都已 <br />经退休的长辈，他们对社会的认识还停留在很久以前，而这个社会已经发生很大的变化呢 <br />。最重要的是，长辈有时候会强求你做一些事情，但是，最终的结果他们是不负责的。只 <br />有你才能对自己负责。 <br /><br /></font>
<img src ="http://www.cppblog.com/threesh/aggbug/16875.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/threesh/" target="_blank">Cpp Fans</a> 2006-12-26 16:51 <a href="http://www.cppblog.com/threesh/archive/2006/12/26/16875.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]ORACLE数据库开发经验 </title><link>http://www.cppblog.com/threesh/archive/2006/12/04/15974.html</link><dc:creator>Cpp Fans</dc:creator><author>Cpp Fans</author><pubDate>Mon, 04 Dec 2006 07:09:00 GMT</pubDate><guid>http://www.cppblog.com/threesh/archive/2006/12/04/15974.html</guid><wfw:comment>http://www.cppblog.com/threesh/comments/15974.html</wfw:comment><comments>http://www.cppblog.com/threesh/archive/2006/12/04/15974.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/threesh/comments/commentRss/15974.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/threesh/services/trackbacks/15974.html</trackback:ping><description><![CDATA[
		<p>
				<font face="verdana, arial, helvetica" size="2">
						<span class="javascript" id="text21204" style="FONT-SIZE: 12px">
								<a href="http://www2.ccw.com.cn/tips/9911/110402_04.asp" target="_blank">http://www2.ccw.com.cn/tips/9911/110402_04.asp</a>
								<br />
								<br />岭澳核电有限公司 <br />黄福同 <br />---- ORACLE数据库作为大型数据库管理系统，近年来一直占有世界上高端数据库的最大份额，其强大而完善的数据库管理功能，以及ORACLE公司推陈出新的不断努力，一直成为IT业界瞩目的焦点。岭澳核电站的数据库平台采用了ORACLE7.3作为后端平台，前端选择了ORACLE公司的DEVELOPER 2000 及DESIGNER 2000作为开发工具，采用了目前流行的CLIENT/SERVER模式。本人在ORACLE系统的开发中，就ORACLE的整套开发工具提出一些自己的体会，供同行参考。 <br /><br />---- 一. ORACLE SQL PLUS 使用技巧: <br /><br />---- ①查找重复记录: <br /><br />SELECT DRAWING,DSNO FROM EM5_PIPE_PREFAB<br />WHERE ROWID!=(SELECT MAX(ROWID) FROM EM5<br />_PIPE_PREFAB D<br />WHERE EM5_PIPE_PREFAB.DRAWING=D.DRAWING AND <br />EM5_PIPE_PREFAB.DSNO=D.DSNO);<br />---- 执行上述SQL语句后就可以显示所有DRAWING和DSNO相同且重复的记录。 <br />---- 删除重复记录: <br /><br />DELETE FROM EM5_PIPE_PREFAB <br />WHERE ROWID!=(SELECT MAX(ROWID) FROM EM5<br />_PIPE_PREFAB D<br />WHERE EM5_PIPE_PREFAB.DRAWING=D.DRAWING AND <br />EM5_PIPE_PREFAB.DSNO=D.DSNO);<br />---- 执行上述SQL语句后就可以刪除所有DRAWING和DSNO相同且重复的记录。 <br />---- ② 快速编译所有视图 <br /><br />---- 当在把数据库倒入到新的服务器上后(数据库重建)，需要将视图重新编译一遍，因为该表空间视图到其它表空间的表的连接会出现问题，可以利用PL/SQL的语言特性，快速编译。 <br /><br />SQL &gt;SPOOL ON.SQL<br />SQL &gt;SELECT ‘ALTER VIEW ‘||TNAME||’<br />COMPILE;’ FROM TAB;<br />SQL &gt;SPOOL OFF<br />然后执行ON.SQL即可。<br />SQL &gt;@ON.SQL<br />当然，授权和创建同义词也可以快速进行，如：<br />SQL &gt;SELECT ‘GRANT SELECT ON ’<br />||TNAME||’ TO USERNAME;’ FROM TAB;<br />SQL &gt;SELECT ‘CREATE SYNONYM <br />‘||TNAME||’ FOR USERNAME.’||TNAME||’;’ FROM TAB;<br /><br />③ 用外联接提高表连接的查询速度<br />在作表连接(常用于视图)时，常使用以下方法来查询数据:<br />SELECT PAY_NO, PROJECT_NAME<br />FROM A<br />WHERE A.PAY_NO NOT IN (SELECT PAY_<br />NO FROM B WHERE VALUE &gt;=120000);<br />---- 但是若表A有10000条记录，表B有10000条记录，则要用掉30分钟才能查完，主要因为NOT IN要进行一条一条的比较，共需要10000*10000次比较后，才能得到结果。该用外联接后，可以缩短到1分左右的时间: <br />SELECT PAY_NO,PROJECT_NAME <br />FROM A,B<br />WHERE A.PAY_NO=B.PAY_NO(+)<br />AND B.PAY_NO IS NULL <br />AND B.VALUE &gt;=12000;<br />---- ④ 怎样读写文本型操作系统文件 <br />---- 在PL/SQL 3.3以上的版本中，UTL_FILE包允许用户通过PL/SQL读写操作系统文件。如下： <br /><br />DECALRE<br />FILE_HANDLE UTL_FILE.FILE_TYPE;<br />BEGIN<br />FILE_HANDLE:=UTL_FILE.FOPEN(<br />‘C:\’,’TEST.TXT’,’A’);<br />UTL_FILE.PUT_LINE(FILE_HANDLE,’<br />HELLO,IT’S A TEST TXT FILE’);<br />UTL_FILE.FCLOSE(FILE_HANDLE);<br />END;<br />---- 相关UTL_FILE数据库包详细信息可以参见相关资料。<br /><br /></span>
				</font>
		</p>
		<p>
				<font face="verdana, arial, helvetica" size="2">
						<span class="javascript" id="text21205" style="FONT-SIZE: 12px">---- ⑤ 怎样在数据库触发器中使用列的新值与旧值 <br /><br />---- 在数据库触发器中几乎总是要使用触发器基表的列值，如果某条语句需要某列修改前的值，使用:OLD就可以了，使用某列修改后的新值，用:NEW就可以了。如:OLD.DEPT_NO,:NEW.DEPT_NO。 <br /><br />---- 二.ORACLE DEVELOPER 2000使用技巧： <br /><br />---- ① 改变FORM(FMX模块)运行时的Runform4.5的题头: <br /><br />---- DEVELOPER2000中FMX默认题头为：Developer/2000 Forms Runtime for Windows 95 / NT 你可以改为自己定义的标题, <br /><br />---- 1. 在Form级触发器中添加触发WHEN-NEW-FORM-INSTANCE <br /><br />---- 2. 在此触发器中写如下代码： <br /><br />set_window_property(FORMS_MDI_WINDOW,TITLE,'POINT<br />SYSTEM 欢迎使用');<br />---- ② 如何隐藏菜单中的window选项: <br />---- 在创建自己的菜单时，最后选项总有window项，下面介绍如何去掉它, <br /><br />---- 1. 创建一个Menu <br /><br />---- 2. 在Menu中建立一个Item,命名为WINDOW。 <br /><br />---- 3. 设置该Item属性如下: <br /><br />----<br /><br />Menu Item Type:Magic <br />Command Type:Null <br />Magic Item:Window <br />Lable:为空<br /><br />---- ③ 怎样创建动态下拉列表List <br />---- Developer 2000 中的列表是通过设置相关属性而完成数据项的列表设置的，但那只是静态的，有时你想让某项成为动态的列表，随输入数据的改变而改变，就需要动手去编个小程序。下面详细介绍怎样去做: <br /><br />---- 有块EBOP_CABLE_ACCOUNT，下有SPECIFICATION数据项，当一进入该模块时，就将SPECIFICATION项在数据库中存储的值动态显示出来，先在Form4.5中建立一个PRCEDURE，命名为DYN_LIST: <br /><br />PROCEDURE DYN_LIST IS<br />CURSOR C1 IS <br />SELECT DISTINCT(SPECIFICATION) <br />FROM EBOP_CABLE_ACCOUNT;<br />CNT NUMBER;<br />i NUMBER; <br />TNAME EBOP_CABLE_<br />ACCOUNT.SPECIFICATION%TYPE;<br />BEGIN<br />CLEAR_LIST('EBOP_CABLE_<br />ACCOUNT.SPECIFICATION');<br />SELECT COUNT(DISTINCT<br />(SPECIFICATION)) INTO CNT FROM EBOP<br />_CABLE_ACCOUNT;<br />open C1;<br />FOR i IN 1..CNT LOOP<br />FETCH C1 INTO TNAME;<br />EXIT WHEN C1%NOTFOUND <br />OR C1%NOTFOUND IS NULL;<br />ADD_LIST_ELEMENT<br />('EBOP_CABLE_ACCOUNT<br />.SPECIFICATION',i,TNAME,TNAME);<br />END LOOP;<br />DELETE_LIST_ELEMENT<br />('EBOP_CABLE_ACCOUNT.SPECIFICATION',CNT+1);<br />CLOSE C1;<br />END;<br />然后在FORM的WHEN-NEW<br />-FORM-INSTANCE触发子中加入一行：<br />DYN_LIST;<br />---- 这样一进入该FMX，就会动态刷新该列表。除此之外，SPECIFICATION数据项改为列表项。 <br />---- ④ 当显示多条记录且数据项特别多时，如何组织录入及显示界面: <br /><br />---- 如上图所示，PRN代码及设备代码在画布1(CONTENT型)上，其它数据项在画布2(STACK型)上，所有数据项为一个表的列或一个块的数据项。在拉动水平滚动条时或用TAB或敲回车键时，将看到全部数据项。这种排布方法适用于数据项特别多又想显示多条记录时用。主要制作顺序为：先建立两个画布，画布1(CONTENT型)，画布2(STACK型)，然后建立块，选画布时用画布1，这样所有项都显示在画布1上，然后选中除PRN代码及设备代码之外的所有数据项，选TOOLS菜单下的PROPERTIES选项，将这些数据项的CANVAS属性选为画布2(STACK型)，然后调整整体位置就可以了。 <br /><br />---- ⑤ 如何在FORM的受限触发子中提交保存数据 <br /><br />---- 在FORM中很多触发子是不能用COMMIT WORK语句的，当你在该触发子中使用了UPDATE，DELETE等操作并想立即存盘时，就需要COMMIT WORK语句了。首先在服务器端建立DB_SQL_COMMIT这个过程(采用ORACLE7.3数据库)， <br /><br />PROCEDURE DB_SQL_COMMIT IS<br />source_cursor integer;<br />ignore integer;<br />V7 NUMBER :=2;<br />BEGIN<br />source_cursor:=dbms_sql.open_cursor;<br />dbms_sql.parse(source_cursor,'COMMIT WORK',V7);<br />ignore:=dbms_sql.execute(source_cursor);<br />DBMS_SQL.CLOSE_CURSOR(source_cursor);<br />END;<br />---- 然后在FORM中该触发子中调用过程DB_SQL_COMMIT;就可以了，当然你可以根据自己需要将该过程加入参数，这样通过参数可以得到执行DML语句的权限。<br /><br /> ⑥ 如何在FORM中实现某数据项自动按记录序号加一操作 <br /><br />---- 设块名为VO,要操作的数据项为VO_ID,在该块中建立块级触发子WHEN-CREATE- RECORD，加入如下代码： <br /><br />:VO_ID:=:System.Trigger_Record;<br />---- 这样每当生成新记录时VO_ID就会自动加一了。 <br />---- ⑦ 如何在一个FORM中调用另一个FORM，或在一个块中调用另一个块时显示特定的记录有时用户会要求在调用另一个FORM时，只显示相关的记录，举例如下，在一个FORM的块中有一个按钮，在按钮触发子中加入如下代码： <br /><br />DECLARE<br />PM <br />PARAMLIST;<br />BEGIN<br />PM:=GET_PARAMETER_LIST('PM');<br />IF NOT ID_NULL(PM) THEN<br />DESTROY_PARAMETER_LIST('PM');<br />END IF;<br />PM:=CREATE_PARAMETER_LIST('PM');<br />......................<br />ADD_PARAMETER(PM,'THE_WHERE',<br />TEXT_PARAMETER,'EM_NAME=''EM4'' <br />AND EM_PROJECT_NAME=''支架预制''');<br />OPEN_FORM('PAYMENT',ACTIVATE,SESSION,PM);<br />END；<br />---- 其中EM_NAME，EM_PROJECT_NAME为本FORM某块的数据项，PAYMENT为要调用的FORM模块。这样通过传递参数列表就可以得到想要的结果。在FORM PAYMENT.FMB中，建立一参数THE_WHERE，CHAR型，长1000，然后在PAYMENT.FMB中建立FORM级触发子WHEN-NEW-FORM-INSTANCE，在该触发子中加入以下语句： <br />IF :PARAMETER.THE_WHERE IS NOT NULL THEN<br />SET_BLOCK_PROPERTY('PAYMENT',<br />DEFAULT_WHERE,:PARAMETER.THE_WHERE);<br />END IF;<br />---- 其中PAYMENT为要显示的块，这样通过参数传递就得到想要的某些特定条件的数据了。 <br />---- ⑧ 在FORM中当有主从块时，连续输入记录如何避免被不断的提示保存： <br /><br />---- 每输入一条主记录和若干条该主记录的从记录后，此时再导航到主块输下一条记录，FORM就会提示你是否要保存记录，而你并不希望FORM提示，让它自动保存，此时你可以到Program Units中找到过程PROCEDURE Clear_All_Master_Details，然后在这个过程中找到语句 <br /><br />Clear_Block(ASK_COMMIT); <br />---- 将其改为Clear_Block(DO_COMMIT);就可以了。 <br />---- ⑨ 在Report开始时选择排序项: <br /><br />---- 在报表开始的Parameter Form中选择报表按哪个数据项排序， <br /><br />---- 1. 先在USER PARAMETER 中创建SORT参数，为字符型，长20。 <br /><br />---- 2. 初始值选’责任方’,然后将这四个值输入到DATA SELECTION中，形成列表。 <br /><br />---- 3. 然后处理QUERY中的SQL语句: <br /><br />select CHARGER,FCO_NO,EM_NAME,FCO<br />_NO,DESCRIPTION, FCR_POINT <br />from FCR_MAIN <br />ORDER BY DECODE(:SORT,'责任方',CHARGER,'FCO号',<br />FCO_NO,'FCR号',FCR_NO,'FCR号',EM_NAME)<br /><br /></span>
				</font>
		</p>
		<p>
				<font face="verdana, arial, helvetica" size="2">
						<span class="javascript" id="text21207" style="FONT-SIZE: 12px">---- ⑩ 在Developer 2000中如何读写操作系统文件 <br />---- 在用Developer 2000的开发工具开发应用程序时，经常碰到需要读写外部文件的问题，可以用ORACLE 带的包TEXT_IO来完成这项需求。例如: <br /><br />DECLARE<br />IN_FILE TEXT_IO.FILE_TYPE;<br />OUT_FILE TEXT_IO.FILE_TYPE;<br />LINE_BUFER VARCHAR2(80); <br />/*若不用IN_FILE,可以将各字段联接在一起赋值给此变量*/<br />BEGIN<br />IN_FILE:=TEXT_IO.FOPEN<br />(‘C:\TEMP\TEST1.TXT’,’r’);<br />OUT_FILE:=TEXT_IO.FOPEN<br />(‘C:\TEMP\TEST2.TXT’,’w+’);<br />LOOP<br />TEXT_IO.GET_LINE(IN_FILE,LINE_BUFER);<br />TEXT_IO.PUT(LINE_BUFER);<br />TEXT_IO.NEW_LINE;<br />TEXT_IO.PUT_LINE(OUT_FILE,LINE_BUFER);<br />END LOOP;<br />EXCEPTION<br />WHEN no_data_found THEN<br />TEXT_IO.PUT_LINE(‘CLOSING THE FILE ,PLEASE WAITING....’);<br />TEXT_IO.FCLOSE(IN_FILE);<br />TEXT_IO.FCLOSE(OUT_FILE);<br />END;<br />---- 三.数据库管理 <br /><br />---- ① 在删除一个表中的全部数据时，须使用TRUNCATE TABLE 表名;因为用DROP TABLE，DELETE * FROM 表名时，TABLESPACE表空间该表的占用空间并未释放，反复几次DROP，DELETE操作后，该TABLESPACE上百兆的空间就被耗光了。 <br /><br />---- ② 数据库文件的移动方法 <br /><br />---- 当想将数据库文件移动到另外一个目录下时，可以用ALTER DATABASE命令来移动(比ALTER TABLESPACE适用性强)： <br /><br />---- 1. 使用SERVER MANAGER关闭实例. <br /><br />SVRMGR &gt; connect internal;<br />SVRMGR &gt; shutdown;<br />SVRMGR &gt;exit;<br />---- 2. 使用操作系统命令来移动数据库文件位置(假设这里操作系统为SOLARIS 2.6). 在UNIX中用 mv命令可以把文件移动到新的位置， <br /><br />#mv /ora13/orarun/document.dbf /ora12/orarun<br />---- 3. 装载数据库并用alter database命令来改变数据库中的文件名. <br />SVRMGR &gt; connect internal;<br />SVRMGR &gt; startup mount RUN73;<br />SVRMGR &gt; alter database rename file<br />&gt; ‘/ ora13/orarun/document.dbf’<br />&gt; ‘/ ora12/orarun/document.dbf’;<br />---- 4. 启动实例. <br /><br />SVRMGR &gt; alter database open;<br />---- (huangfutong@china.com) <br /><br />---- ORACLE数据库开发经验总结</span>
				</font>
		</p>
<img src ="http://www.cppblog.com/threesh/aggbug/15974.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/threesh/" target="_blank">Cpp Fans</a> 2006-12-04 15:09 <a href="http://www.cppblog.com/threesh/archive/2006/12/04/15974.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>程序员,难道你该跟在C#的后面?</title><link>http://www.cppblog.com/threesh/archive/2006/11/23/15571.html</link><dc:creator>Cpp Fans</dc:creator><author>Cpp Fans</author><pubDate>Thu, 23 Nov 2006 00:53:00 GMT</pubDate><guid>http://www.cppblog.com/threesh/archive/2006/11/23/15571.html</guid><wfw:comment>http://www.cppblog.com/threesh/comments/15571.html</wfw:comment><comments>http://www.cppblog.com/threesh/archive/2006/11/23/15571.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/threesh/comments/commentRss/15571.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/threesh/services/trackbacks/15571.html</trackback:ping><description><![CDATA[
		<p>
				<font size="2">C++、DELPHI、JAVA……这些耀眼的名字不仅占据了程序员的生活，而且似乎已经成为了某种信仰。这世界上好像没有什么比编程工具更能牵动程序员的心了。</font>
		</p>
		<br />
		<p>
				<font size="2">微软，这头已被法官和黑客们折腾得既疲惫又恼怒的狮子，发誓要保住它头上的王冠。于是拼尽全力，拿出了看家的本事——.NET战略。而作为 .NET的核心开发语言，C#就顺理成章地浮出了水面。</font>
		</p>
		<p>
				<font size="2">　　有选择就有痛苦，程序员，你选择跟在谁的后面？</font>
		</p>
		<p>
				<font size="2">　　要找出答案就不得不来作一番比较和预测：</font>
		</p>
		<p>
				<font size="2">　　先除去一切非技术方面的因素不议，C# 无疑是自盘古开天以来这个人类地球上最好的编程语言，它几乎集中了所有关于软件开发和软件工程研究的最新成果。面向对象、组件技术、类型安全、版本控制、跨平台异常处理、自动内存管理、代码安全管理……你不可能在另外的一种语言中找到所有这些特性。也许的也许，这时，你想到了JAVA，然而，C# 确实是走得更远。<br />　<br />　　回顾历史，非技术的因素好像往往更能决定一个产品的未来，尤其在计算机软件的历史上。</font>
		</p>
		<p>
				<font size="2">　　技术卓越的产品，如OS/2、Mac OS、UNIX等，都败在了Windows那漂亮的脸蛋儿下。而这一次，微软的角色好像从一个赤手空拳的革命者变成了仗势欺人的老地主，如果真是要变天，那C# 这孩子岂不是投错了胎？也可能情形并非如此糟糕，毕竟瘦死的骆驼比马大，而且C# 已经提交给了一个标准化组织，一旦成了国际标准，说不准真有哪个大侠（也有可能是微软自己）给移植到Linux 和别的平台上。</font>
		</p>
		<p>
				<font size="2">　　要是那样的话，JAVA小弟可就惨了。因为JAVA的用户主要是网络服务的开发者和嵌入式设备软件的开发者，嵌入式设备软件不是C# 的用武之地，而在网络服务方面，C# 的即时编译和本地代码Cache方案比JAVA虚拟机更具有绝对的性能优势。何况C# 一旦成为一个像C++ 一样的公共的标准，软件开发商既可以省去JAVA的许可证费用，也不必担心成为微软的奴隶，那些反微软的人士和主张厂商独立的人士可能也不会有什么意见。这可能正是微软所期待的。</font>
		</p>
		<p>
				<font size="2">　　再看，C# 和传统通用快速开发工具—VB、DELPHI等的较量，又是地地道道的白刃战。可能到时最惨的程序员就是VB程序员，在微软，VB就像离任的克林顿，不但失去了所有的光辉，而且乱事缠身。想想吧，VB6写的项目必须用转换工具转换成基于.NET的代码才能在VB7中调入，几乎面目全非。由于VB7遵循为迎合.NET而建立的通用语言规范（CLS），几乎把所有原来只在C++、JAVA等语言中可以运用的特性统统加了进来，只是语法和原来兼容。如果你是第一次在VB7中看到自己的旧VB6项目转换之后的代码，一定要当心你的心脏！所以，努力吧，别告诉我你将就此退休。DELPHI的状况也好不到哪里去，原来的看家本领是做起应用来又快又好，可现在看看最新的VS.NET Beta 1, 你会感到如此熟悉，众多的属性列表、组件……，唉，只有感叹的份了！　　最后，我们细品品，其实在编程语言中真正的霸主多年来一直就是C++，所有的操作系统和绝大多数的商品软件都是用C++作为主要开发语言的。JAVA的程序员绝大多数也是C++的爱好者，PHP的成功里面也有类似C++的语法的功劳。在操作系统、设备驱动程序、视频游戏等领域，C++在很长的时间内仍将占据主要地位，而在数量最大的应用软件的开发上，C# 很可能取代C++的位置。</font>
		</p>
		<p>
				<font size="2">　　首先，C# 和JAVA一样，简直就是照搬了C++的部分语法，因此，对于数量众多的C++程序员学习起来很容易上手，另外，对于新手来说，比C++要简单一些。其次，Windows是目前占垄断地位的平台，而开发Windows应用，当然微软的声音是不能忽略的。最重要的是，相对于C++，用C# 开发应用软件可以大大缩短开发周期，同时可以利用原来除用户界面代码之外的C++代码。</font>
		</p>
		<p>
				<font size="2">　　人无完人，编程语言它也是如此，C# 也有弱点。</font>
		</p>
		<p>
				<font size="2">　　首先，在大量的现有Windows平台上，C# 的程序还不能运行，因为C# 程序需要 .NET运行库作为基础，而 .NET运行库将作为新一代的Windows（Whistler）的一部分发行， 或以Service Pack的形式提交给Windows Me 和 Windows 2000用户。所以在近期，C# 会主要在服务器上得到应用。其次，C# 能够使用的组件或库还只有 .NET 运行库等很少的选择，没有丰富的第三方软件库可用，这需要有一个过程，同时各软件开发商的支持也很重要。第三，JAVA的成功因素里有一些是反微软阵营的吹捧，虽然“只写一次，到处运行”只是一句口号，但毕竟已经是一种成熟的技术。而C# 的鼓吹者目前只有名声不佳的微软，且只能运行在Windows上。实际上这两种语言都不是不可替代的，理智的说，对软件开发商而言，什么用的最熟什么就是最好的工具。尤其对C++的使用者，C# 没有带来任何新东西，因为.NET运行库在C++中也可以使用，没有要换的绝对的理由。</font>
		</p>
		<p>
				<font size="2">　　据以上分析，我们可以理所当然地得出结论：近几年，C# 将不可避免地崛起，在Windows平台上成为主角，而JAVA将在UNIX、Linux等平台上成为霸主，C++ 将继续在系统软件领域大展拳脚。非常有意思的是，这些语言的语法极其接近，因为JAVA和C# 都是由C++发展而来的。其他的开发工具当然还会在相当长的时间里继续他们的旅程，不过在市场份额上，将不可避免地受到冲击。</font>
		</p>
<img src ="http://www.cppblog.com/threesh/aggbug/15571.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/threesh/" target="_blank">Cpp Fans</a> 2006-11-23 08:53 <a href="http://www.cppblog.com/threesh/archive/2006/11/23/15571.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PeopleSoft的前景及ERP的未来 （转载） </title><link>http://www.cppblog.com/threesh/archive/2006/11/20/15470.html</link><dc:creator>Cpp Fans</dc:creator><author>Cpp Fans</author><pubDate>Mon, 20 Nov 2006 11:50:00 GMT</pubDate><guid>http://www.cppblog.com/threesh/archive/2006/11/20/15470.html</guid><wfw:comment>http://www.cppblog.com/threesh/comments/15470.html</wfw:comment><comments>http://www.cppblog.com/threesh/archive/2006/11/20/15470.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/threesh/comments/commentRss/15470.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/threesh/services/trackbacks/15470.html</trackback:ping><description><![CDATA[
		<p>
				<font face="verdana, arial, helvetica" size="2">
						<span class="javascript" id="text5044023" style="FONT-SIZE: 12px">
								<br />Oracle收购PeopleSoft并不会给CIO们带来什么恐慌，这只意味着传统ERP时代的结束。对于你的业务来说，它也许带来了降低成本增加收益的机会。<br /><br />去年二月，Corning业务流程架构的负责人Rick Beers，汇聚了来自Bausch &amp; Lomb公司、Harris公司、Leggett &amp; Platt 公司以及其它5家世界五百强公司的CIO们在亚特兰大举行了一次特别的峰会。大家分享了世界上最大的几家PeopleSoft用户的特点。Beers召集这次会议的目的就是解决目前摆在他们面前的难题：如何通过应用增加企业绩效。<br /><br />换句话说，当拥有13000家用户的PeopleSoft被Oracle以103亿美元的价格收购后，这些大型公司所头疼的已经不是所谓的恶意收购事件了，而是如何使这些应用继续为企业提高绩效。<br /><br />Beers的峰会在收购以前的几个月就开始计划了，收购成功与否并不会影响到会议的进程。不管媒体和其他CIO们怎样看待这个问题，这八家公司的观点就如Reers所说的“Oracle和PeopleSoft的交易并不会改变很多”。<br /><br />Beers等人早已明白，他们目前的企业应用模型，在Oracle采取收购行动之前就已经出现了问题。<br /><br />Beers说，“我在这里想要说的就是，大家应该注意我们现在的处境了，如果我们不能围绕业务模型来架构我们的ERP，那么我们最终会因为互操作性而不得不放弃一些系统。绩效应该是通过集成现有应用来体现的，而不是简简单单的几个新特性就能满足的，如果是那样的我们将在ERP上得不到太多的收益。”<br /><br />在这篇文章，我们将针对使用PeopleSoft或J.D. Edwards的用户，向CIO们介绍如何通过短期的战略性调整来应对Beers等人所意识到的长期复杂性的变化。<br /><br />现在的企业应用市场的两大巨头是SAP和Oracle。兼并PeopleSoft后的Oracle目前所拥有的客户已经可以和SAP有所竞争了。这也就是这次兼并的闪亮点。现在的Oracle就是百事可乐，而SAP就如同可口可乐。同时使用两套平台的用户就好比是同时饮用两种饮料的消费者一样。这两大巨头都在努力劝说他们的用户，说自己才是是“真正的”企业应用。<br /><br />他们之间的拉锯战已经开始了。SAP最近收购了一家支持PeopleSoft产品的软件公司TomorrowNow，同时承诺“先是支持，然后可以升级到SAP”来劝说PeopleSoft用户离开Oracle。而Oracle的回馈是提供“比其它公司更长的服务保障”。Oracle的承诺是保留原PeopleSoft的90%的技术人员，PeopleSoft的软件可以升级到第九版本，同时对PeopleSoft平台支持到2013年。Oralce还通过10城市的巡演来安抚CIO们。Oracle的CEO Phillips说，“我们花费100亿美元不是想让这些客户走掉”。“我们非常有信心让客户满意，你们之前什么时候听到过Oracle如此的对客户承诺？”<br /><br />有些分析家们趣谈到，PeopleSoft用户得到的优厚待遇足以让那些Oracle的用户嫉妒了。<br /><br />其实在Oracle和SAP向PeopleSoft的用户献殷情的同时，其它独立供应商也开始出来争夺市场了，他们劝说客户远离那些维护费用高昂的大供应商。处于第二梯队的企业应用供应商如Microsoft、Lawson等，也给CIO们的选择增加了难度。Microsoft刚刚和一个公司合作推出了基于Web的用于高等教育的应用系统，很明显这是瞄准了由PeopleSoft所掌控的教育市场。外包服务供应商业也会参和进来，他们热情的说到，现在该是时候把业务外包出去了？<br /><br />“我被那些想要我钱的人包围了”，Decorative Concepts公司的CIO这样说道，“他们不停的打电话过来，今天我已经接到三个了”。Decorative Concepts运行的是J.D. Edwards系统。<br /><br />Oracle许诺对PeopleSoft平台支持，同时还为CIO们做了详细的安排，告诉他们下步该怎么走。<br /><br />第一步：确定角色。<br /><br />当Oracle购买PeopleSoft后，你们公司的应用平台将会出现两种情况，“要么不变，要么变动”。<br /><br />A. 如果选择“不变”。说明你的系统运行的很顺畅，业务流程也不会发生太大的变化。<br /><br />这样的话，你只要专注于内部就行了。<br /><br />你只要对你的应用平台做一个今后一年、三年或五年的风险估价就行了。考虑你到底打算支付多少，会出现什么等级的革新，是运行一个ERP平台还是多个，或者你是不是只打算在内部使用。<br /><br />Oracle的承诺是以客户为中心<br /><br />Oracle的CEO Phillips说，“我们花费100亿美元不是想让这些客户走掉”。“我们非常有信心让客户满意，你们之前什么时候听到过Oracle如此的对客户承诺？”<br /><br />在这样的情况下你的日子将非常好过。IDC的分析家Evan Quinn说，“对于已经运行了PeopleSoft的那些用户，这种情况是再好不过了。Oracle作了长期的安排，接下来就只是执行就行了”。<br /><br />David Gray，马萨诸塞州大学的CIO，选择的就是“不变”。他希望他们的PeopleSoft应用可以延续20年。“PeopleSoft很多产品的市场都要比Oracle的好，我们希望Oracle能够看到这一点。就此我们计划同Oracle来一次会议。我们不会问到太多的细节，但是希望得到更多的收益。”<br /><br />B. 如果是“变动”。那意味着你打算整合、升级或增加新的应用，同时你的业务流程也将会有大的变动。<br /><br />这时你就要往外看了。<br /><br />你要招待这些供应商，同时看着他们在那里互相竞争。同时你不的不进行一系列的整合，还要为你的整合做一个预算。你也许会有8个财务系统，4个是PeopleSoft的，一个是SAP的，一个是Oracle的，一个是Lawson的，还有一个是Microsoft的。这时你就必须要保证它们不会出现问题。每项合同都需要出现一些额外的需求。<br /><br />基本上，你就在也不可能安稳了，你要在众多的被选方案中选出最佳的。但是，你必须要考虑如何解决目前的问题。<br /><br />一个大型保险公司的系统管理员，打算引进新的系统，那么这就属于“变动”了。他不得不认真评价供应商。他说，“我们举行了两次同样的讨论，以方便供应商介绍他们的方案”。“我们大约选择了20多家相关的企业应用软件供应商来展示他们的方案。我们的重点主要集中在集成上。<br /><br />Quinn认为你可以用六个月到一年的时间来决定你的供应商。<br /><br />Oracle需要你！<br /><br />Oracle承诺对PeopleSoft的支持将持续到2013年，这做起来并不难，因为Oracle知道在接下来的8年应该做什么。Oracle最担心的是PeopleSoft客户的流失，因为Oralce以103亿美元的价格购买PeopleSoft就相当于以790,000美元的价格购买了其13000家用户，那么每少一个客户都会一定程度上降低其投资回报率。<br /><br />如果Oracle想要保留PeopleSoft的用户，那么他就要在短期内给出解决方案，这个拖的越久越不利。尽管Oracle愿意提供8年维护支持，但是没有哪家公司是愿意同时维护两套产品的。通常软件供应商所给出的产品生命周期是18个月，但Oracle的Phillips说，“这没有任何冲突，产品本身是有活力的，我们不会要求任何人改变什么。”<br /><br />目前，PelpleSoft每年可以从客户那里拿到8亿美元的许可费用，但这和Oracle100亿美元的出价还是有段距离的。目前Oracle还不可能很快拿出方案实现其“一站式服务”，即一点登陆实现对其它软件的端到端操作。最后，Oracle肯定等不到8年就会要求他的客户向Oracle应用或数据库转移，如果不那样的话维护费用就会相当大。这两种情况也许会同时发生。<br /><br />Oracle的发言人Karen Tillman解释道，“很明显，我们做这次收购交易部分原因是想推销我们自己的产品，但这并不意味我们的客户非要那样做”<br /><br />第二步：下一步怎么走？<br /><br />对于PeopleSoft用户这里有3个方向。<br /><br />A.耐心等待。你也许是属于上面讨论的“不变”的那一类，这时你将相当轻松，只要静静的享用ERP所带了价值就好了。<br /><br />Umass公司的Gray认为类似于这样的实施算是“较稳定的”。同时他又补充说，“很明显我们不想有太多的变动”，“但这并不代表就没有压力了，按照我的经验来看，我们不会因为Oracle的承诺而就此拥有太多的特殊待遇”。<br /><br />对于Gray来说，“耐心等待”并不代表什么都不用做了。他打算同Oracle来一次会面，以了解Oracle将如何处理PeopleSoft的代码。同时他还准备派几个职员去参加Oracle在内华达州的一个会议，讨论Oracle将来的价格和创新。面对市场激烈的竞争，他不得不考虑如何去降低成本来相应客户的需求。<br /><br />“你必须要让你的组织稳定，业务功能要运行流畅” Gray说，“我们必须要弄清楚供应商的解决方案，以及为此我们要支付的费用”<br /><br />表面上看起来，选择“耐心等待”的Gray不需要任何的变动。Gray继续运行他的PeopleSoft系统，支持人员还是原来那些，最多只是换个工作牌而已。唯一的风险就是维护费用可能增加。Gray同时还提到“在向Oracle转变的过程中还是有一些摩擦的，一些关于支持的问题没能及时的得到回答。同时还存在过渡点，在这些点上我们也不知道出了问题该找谁负责”。Gray认为这主要是因为物理上的合并造成的。尽管现在还有很多问题没有得到回到，但比刚开始的时候稳定多了。<br /><br />这并不会给Gray带来太多的麻烦，他可以选择维持原样，如果有必要的话也可以在今后对ERP模型做一些改动。<br /><br />Gray说，“很明显，这还留有很大的余地”。<br /><br />B、寻求第三方支持。不管你在第一步里选择的是“变动”还是“不变”，从经济的角度来开，为了节约成本，你有可能改变目前的维护、支持模式。<br /><br />Big Lots的副总裁兼CIO John Zavada在两年前看到了PeopleSoft的维护合同，发现在过去的五年里成本竟然上升到了原来的两倍。<br /><br />将PeopleSoft升级到8.3是相当痛苦的，他回忆道。这即花费了时间也花费了不少的钱，整整经过一年的时间系统才达到稳定。据Zavada的透漏，他们之所以必须升级系统仅仅是因为合同的强制规定。<br /><br />“我们再也不会因为维护而受到你们的责备，我们宁愿去维护一项服务，我们要寻求新的方式”，John Zavada这样向PeopleSoft说。<br /><br />这种新的方式就是由TomorrowNow提供的第三方支持，TomorrowNow将负责今后10年对目前版本的PeopleSoft的支持，成本要比依靠软件供应商低的多。Zavada说，“我们再也不需要升级了，不停的升级只能给我们带来维护上的痛苦，带来的收益却是微呼甚微”。<br /><br />目前来说，虽然TomorrowNow在二月份被SAP收购了，但所有的一切都进行的比较顺利。<br /><br />John Zavada说他的ROI比两年前少了，如果他们五年前就决定上新的ERP系统的话，那将会节约很多钱。“我不知道道业界能不能理解CIO们看到的这种差别” John Zavada说，“我们对一家又一家的软件进行评估，同时问我们自己是否能在总体维护上有所节约”。<br /><br />选择第三方支持是个很不错的选择。你为了维护系统需要支付费用，而支持合同又规定要进行系统升级，这样你有不得不寻求更多的支持。Bridgestone Europe的CIO Joe O'Neill之所以选择第三方供应商，是因为PeopleSoft一年的维护费用是20万美元，Oracle 的是22万美元，而如果你选择第三方的话只需要2.9万美元。<br /><br />选择第三方支持的CIO就是把ERP看成了商品。他们认为软件最好不要有太多的革新，升级也是不必要的，因为在升级上所花的费用是不值的。<br /><br />C.升级到Oracle的企业应用平台。你也许在第一步里选择则的是“变动”，那么你也学正在计划升级或是更换。你还是觉得ERP有很多可以革新的地方。<br /><br />Steve Sutherland，商业房地产评估公司CB Richard Ellis的CIO。当他被问到Oracle收购PeopleSoft会给他们公司的PeopleSoft ERP带来什么影响时，他首先给我们看了一封电子邮件：<br /><br />1.PeopleSoft的咨询将会得到提高，因为Oracle的咨询更专业些。<br /><br />2.价格会更透明。<br /><br />3.从长期来看，这更有利于财务应用与数据库之间的集成。<br /><br />像Sutherland这样的CIO之所以选择Oracle，是因为他们正处在升级的过程中。他们的PeopleSoft实施处在这样一个情形“我们现在正在实施HR模块，我们已经有了财务模块，同时我们也购买了CRM，并将很快运行起来”，对CIO们来说简单就是美，最好的方式就是只有一家供应商，一个许可证。<br /><br />“对我们这样的公司来说，我不想改变我们目前的模式” Sutherland说，“如果把每年的维护费用同自己内部开发的费用相比，我们是决不会那样做的，支付维护费用对我们来说划算的多。”<br /><br />Sutherland认为，“我们不希望Oracle撤销掉那些我们认为是重要的一些资源。因此我告诉他们我们想要保留什么。目前来说，他们的支持现在更强大了。”<br /><br />一些CIO担心，PeopleSoft的精华，如友好和稳定的人力资源和财务系统，将会在向Oracle的过渡中消失掉。但是Sutherland却不这么认为，他认为“我们已经看到了这两者结合后的力量，这两块的优势只能让这家公司收益，因此他们是不会就这么消亡的。”。<br /><br />第三步，将来怎么办？<br /><br />Oracle认为企业应用软件一定要整合起来。而对于Oracle本身来说，现在要做的就是将三家的代码（包括PeopleSoft和J.D. Edwards）整合在一个平台上，这个平台将以Oracle数据库和应用服务器为中心，并使用基于面相服务的架构SOA。目前Oracle还没有花太大的精力在这块市场上。SAP推出的基于SOA的ERP称为NetWeave。一些其它的第三方供应商如IBM也提供了工具和服务来帮助企业建立自己的SOA架构，因此这就给那些想要离开Oracle和SAP的用户提供了更多的选择。<br /><br />当Rick Beers召集CIO们在亚特兰大开会时，他就考虑到了SOA。<br /><br />SOA的原理很简单：所有的技术实现体现为一个业务流程，例如，“信用检查”，就是一个服务，它不像ERP应用那么神秘。服务由不同的应用组合在一起。他们通过标准的接口与其它的服务和应利用进行通信。<br /><br />在SOA世界里，伴随着业务流的是应用，例如SAP的财务系统可以访问PeopleSoft的HR系统。SOA作为集成层可以避免只能只用单一ERP系统的情形出现。通过使用集成层，我们再也不用为繁琐的维护头疼，而尽情的体验ERP带来的收益。如果你在不同的供应链上管理了多个业务流程，那么你也许最需要的就是在不同的平台上进行业务流的通信。<br /><br />对于Innovation 的CEO Stephanie Race 来说，SOA的概念已经是十几年前的了。Innovation曾经在多家大公司工作过，这也包括Corning。用SOA来代替ERP听起来似乎有些新，但是它已经是一个相当热的话题了。<br /><br />其实除了SOA，业务流程外包（BPO）也是一个新的发展。对于那些把ERP作为常用功能的用户，BPO可以让他们远离升级、支持和维护。让IBM、埃森哲或其它厂商来管理这些业务功能，并应对那些软件供应商。SAP和Oracle目前也在抢夺外包市场。Phillips说，目前只有“几百个”客户签订了他们的随需应变（on-demand）业务，但Oracle的目标是在五年之内要让15%的客户选用外包模式。<br /><br />ERP的今天和明天。<br /><br />其实这两种前景是可以结合起来的。服务公司也可以利用SOA来管理业务流程。同时客户也许只需将一些最基本的ERP功能外包出去，如薪资管理等，而将那些稍复杂的功能保留在企业里。Bridgestone Europe公司的O'Neill正在准备将那些标准的、变化不大的应用转移出去，这样他就可以把精力集中在那些需要革新的领域。<br /><br />这将会有两方面的影响。<br /><br />第一，大的ERP会分解开来。一些复杂的功能如供应链管理、CRM将继续保留，其它的如薪资管理、税务报表等将会分离出去。<br /><br />第二，目前的这种系统维护、支持模式将会改变。这也就意味着CIO们不用在那些通用的流程上做无谓的升级了，他们可以腾出手来关注那些需要革新的地方。以前他们需要自己打水来洗澡，而在外包或SOA世界里是不需要的。<br /><br />但是，新的定价模式将是怎么样的呢？“它是更依赖于服务还是更依赖于架构呢？”Corning的 Beers这样问到。“这个行业将会向哪里发展？如果没有维护合同来支持，系统如何进行革新？”<br /><br />Beers好像要让CIO们想的更远。<br /><br />目前的ERP模式就要消亡，Beers问到，“我们如何来维持革新？我们如何来创造价值？”<br /><br />“下一代企业应用架构到底是怎么个样子？”<br /><br />让我们好好考虑考虑吧。</span>
				</font>
		</p>
<img src ="http://www.cppblog.com/threesh/aggbug/15470.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/threesh/" target="_blank">Cpp Fans</a> 2006-11-20 19:50 <a href="http://www.cppblog.com/threesh/archive/2006/11/20/15470.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]你的定位，你的一生--解读IT人从业方向</title><link>http://www.cppblog.com/threesh/archive/2006/11/16/15264.html</link><dc:creator>Cpp Fans</dc:creator><author>Cpp Fans</author><pubDate>Thu, 16 Nov 2006 14:26:00 GMT</pubDate><guid>http://www.cppblog.com/threesh/archive/2006/11/16/15264.html</guid><wfw:comment>http://www.cppblog.com/threesh/comments/15264.html</wfw:comment><comments>http://www.cppblog.com/threesh/archive/2006/11/16/15264.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/threesh/comments/commentRss/15264.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/threesh/services/trackbacks/15264.html</trackback:ping><description><![CDATA[
		<p>关于企业计算方向 <br />企业计算(Enterprise Computing)是稍时髦较好听的名词，主要是指企业信息系统如：ERP 软件(企业资源规划)、CRM 软件(客户关系管理)、SCM 软件(供应链管理，即物流软件)，银行证券软件财务软件电子商务/政务(包括各种网站)，数据仓库，数据挖掘，商务智能等企业信息管理系统。 </p>
		<p>企业计算领域对人才的需求显然永远是数量最大的因为这是计算机应用最多的领域。搞这方面的好处是: </p>
		<p>(1)人才需求量极大从事企业计算的公司在IT企业中占了大多数。除非在专业上一无特长一般在这一领域总能找到工作。 </p>
		<p>(2)这方面的入门门槛相对较低(如果你的软件功底不是很深可考虑这一领域) </p>
		<p>(3)这方面的大公司较多大公司要赚大钱所以多将精力花在企业计算业务上．如与正规高校软件学院同学目前实习的CitiCorp、HP、IBM、SAP、NEC等公司都属这一领域的公司。如果将来想到大公司找一份相对稳定的工作，从事这方面机会要大很多。 </p>
		<p>但从事这一领域的缺点也是明显的: </p>
		<p>由于这方面的入门门槛相对较低，虽然这方面的人才需求量是最大的，但将来竞争对手会较多。您会发现，即使他原不是学IT专业的人，也许他突击几个月后，做得照样像模像样。特别是当您年纪渐大后，您可能会发现，后面的年轻人可能很容易追上你的水平。如果您将来到国外去工作，你可能会发现从事这领域的人更多且高手如云。当然，若您在这一领域经过多年企业经验，达到较高境界(如能设计软件架构)，则身价永远是高的。国内在这方面人才领域的主要问题是，有经验的高手太少，皮毛了解的人太多。 </p>
		<p>从事企业计算领域，最重要的技能型技术课程是 </p>
		<p>(1) J2EE架构与程序设计</p>
		<p>(2) 大型数据库系统(如Oracle)</p>
		<p>(3) 基于UML的系统分析与设计。<br />如果说还有什么重要的技能，还可将XML与Web Service技术包含进来，若您在这几个领域掌握较好，则不愁找不到工作。其中尤其以J2EE最为重要，目前J2EE已成为企业计算软件开发的最主要平台，也是正规高校软件学院的最重要课程之一。</p>
		<p>尽管该课程只能作为选修课，我们希望正规高校软件学院同学无论将来想从事何种方向，都应学一下J2EE课程，至少可为将来找工作备一手关键功夫。包括想从事嵌入式或其它领域的同学，也是很有必要学一下J2EE的，毕竟J2EE是目前最重要的平台之一，即使您将来不想从事企业计算领域，了解一下J2EE也是必要的，就像一门常识课程一样。</p>
		<p>其它与企业计算关系较密切的技能还包括: Dot Net架构与程序设计、软件测试技术、软件配置管理，该领域较高层次的技能包括数据仓库技术、构件与中间件技术、设计模式等。像通信协议分析与网络程序设计，Unix系统管理等也属有些关系的课程。02级本学期开设的企业计算课程不多，主要是J2EE、Oracle/MSSQL、UML等企业计算领域的最关键技能型技术课程都已学完了。</p>
		<p>您应在空余时间将J2EE，DB、UML等技术再深入地钻研下去，一定要在某个领域有深入的掌握。只是跟着听课，即使学了再多课程也是没用处的，自己钻研下去才是最重要的。只一个J2EE便是博大精深的，足够你啃下去的，钻研下去，您会发现你还要学的相关知识还有很多(包括EJB、XML、Web Service、Design Pattern等)。 </p>
		<p>虽然从事企业计算的人才很多，但以下企业计算领域无论国内外都属稀缺人才: </p>
		<p>(1) 掌握大型ERP系统，主要是SAP系统，包括SAP Basis(系统管理)或SAP ABAP(编程)或SAP功能模块实施(特别是财务模块FI的实施)。SAP顾问身价是最高的，而且非常难找。其它大型ERP系统，掌握PeopleSoft、Oracle Finacial、J.D.Edward、Siebel等大型ERP软件系统的人也很值钱。这方面的人之所以身价奇高，主要是因为这些软件很专业，特别大，很难有D版可学习，只有特大企业(如世界500强，90以上使用SAP)才用得起，而且必须有实际工作经验才能掌握。如果是一个个人人都很容易有机会接触的软件，那么这方面的人通常就不会稀缺。如果大家将来有机会接触学习这些大型ERP软件系统的机会，建议毫不犹豫地抓住，那将捧上一辈的金饭碗。</p>
		<p>在国外，会SAP的人特别值钱。物以稀为贵，这永远是颠扑不破的真理。SAP的价值不仅是因为他是一个ERP软件， 而是其中体现的现代企业管理理念(如根据订货需求自动安排原料采购和生产计划等)。一般500强公司绝不会像国内很多企业那样，用J2EE从头设计企业的ERP系统(即将是怎样的人力投入，而且设计出来的系统怎么可能是完善的)，一定都会使用SAP这样成熟的ERP软件。用不起SAP的公司可能会用J2EE设计ERP系统。 </p>
		<p>(2) 掌握IBM大型机技术的人，如S/390主机，MVS操作系统，JCL作业控制语言，COBOL程序设计语言，DB2关系数据库或IMS层次数据库，CISC中间件交易控制系统等IBM大型机专用技术。国内五大银行，以及国外绝大多数银行的后台系统使用的都是以上平台。IBM大型机号称永不宕机而且平台相对封闭(这样最安全)，所以这些要求在24*7环境中连续运行的关键应用(术语叫mission critical applications)都采用IBM大型机。</p>
		<p>这方面的人才之所以稀缺，是因为会大型机的人都是老人(90年代以前搞IT的人)，全世界新毕业的IT毕业生不可能再去学IBM大型机(这是一种相对“古老“的技术)没有新人补上而银行的系统必须维持下去而且银行还要不断开发新业务(如新的存款品种)虽然对IBM大型机人才的绝对需求量不很大但相对恒定银行到哪里找这方面的新人很难找到. 若好找花旗软件也不会花那么大的代价去培训我们的实习同学了(去年培训20多个人听说公司就花了数十万元培训费). 如果您将来到国外找工作会IBM大型机可能是最好找工作的领域之一了而且保证找的都是大银行等好工作我以前教过的计算机专业90-94级的一些同学凡是毕业后从事大型机开发的现多在国外一些很好的公司工作(有几位同学在各国各公司跳来跳去简直如履平地).</p>
		<p>其实我觉得我们最幸福的同学就是在花旗软件做IBM大型机银行软件的同学这样的机会太难得了.正规高校软件学院00级22班一位同学当初放弃保研看准在花旗软件做大型机并且非常努力还未毕业公司便派她到国外参加一个项目的开发成了项目骨干我觉得她当初选择是完全正确的，01级一位女同学刚刚也自愿放弃了保研机会去花旗做大型机，我们祝愿她将来也能有好的前景。其实像花旗软件主动安排并鼓励员工读在职研究生，这样开明的公司目前并不多的，在职读研也是一种不错的选择，又不会失去自己喜欢的实习工作机会，能兼顾)读书的最终目地还是为了工作. 如果您将来在国外找工作根本没人管您是什么文凭国外企业绝不会花冤枉钱只会招有领域工作经验能立即上手的人用最少的钱在限定的时间完成项目. 而在国内因为人力成本较低公司招聘一很多高学历的人才尽管可能根本用不到这么高的学历但国内的人力太便宜了为什么不高消费一下人才呢这样公司的门面还要好看些。 </p>
		<p>(3) 其它如掌握数据仓库技术的人在国内也很少. 目前最主流的数据仓库平台应是ORACLE的数据仓库工具. 在国外会一些特殊数据仓库的人如NCR/TEREDATA的人非常难找. </p>
		<p>年轻人充满热情喜欢追逐一些热门技术，这当然正确的毕竟学习SAP和大型机的机会毕竟不多毕业时先能找到一份工作是重要的. 但我相信随着年纪的增长大家将来慢慢都会思考的掌握一项竞争对手较少的绝技的重要性将来如果自己到国外工作什么技术最好找工作(对搞软件的人到国外工作或移民是最容易的也许您现在不想但我相信工作多年以后很大一部分同学可能想到国外闯荡一下)你要考虑你今后一生的出路什么样的绝技是最稳定最轻松最高收入的. 搞软件的人当年纪大些时您可能更向住像搞医学人的那样能更多靠经验吃饭而不须整天像年轻人那样不得不去追逐不断出现的软件新技术这个时候也许您也许会发现如果您在SAP或大型机等方面有些绝技您会有很大优势因为这些较偏的领域其技术变化是相对很缓慢的. </p>
		<p>我还记得在2002年时我曾在业余时间与一位德国人合作面试一些IT人才到德国去那时德方各公司发来的需求有很多是SAP和IBM大型机的我们在众多应聘者中最后也未找到一个在这方面有经验甚至是有一点经验的. 相反掌握流行技术的人因太多而不很值钱. </p>
		<p>找工作时不仅要盯着国内市场还要有一种放眼全球的眼光，对搞软件的人您将来完全可能到其它国家去工作. 尤其是在欧美、日本、新加坡等国家，对SAP(包括IBM大型机)人才的需求是很大的。毕竟比同学见得多些提醒同学将来多留意有学习这些绝技的机会一旦有机会建议当仁不让. 国内的人才市场可访问<a href="http://www.51job.com/"><u><font color="#0000ff">www.51job.com</font></u></a>，国外的IT人才需求可访问<a href="http://www.hotjobs.com/"><u><font color="#0000ff">www.hotjobs.com</font></u></a>、<a href="http://www.workopolis.com/"><u><font color="#0000ff">www.workopolis.com</font></u></a>、<a href="http://www.monster.com/"><u><font color="#0000ff">www.monster.com</font></u></a>等著名网站。应经常访问这些网站，以了解市场对人才的具体需求，早做准备。 <a href="http://www.uiok.net/"><u><font color="#0000ff">www.uiok.net</font></u></a></p>
		<p>以上对企业计算领域的观点供大家参考.虽然观点未必正确但确是直言不讳. 总之每个人的脑袋都长在自己脖子上每个人都应有自己的判断. </p>
		<p>还要注意我以上纯粹是从将来就业的角度谈问题. 如果您将来准备到国外读书则应重视基础课像CAssemblyOOPDiscrete MathData StructureOpeating SystemDatabase PrincipleNetworkSoftware EngineeringCompilerDigital CircuitComputer GraphicsComputer Component and Architecture等基础课在国外大学IT专业中一般都能找到相同课程若国内学过到国外读书时一般可申请免修一部分. 但我也想提醒同学如果您将来毕业时万一申请国外大学不成不得不去找工作时，若只将精力花在这些IT专业学生都会的基础课上(传统IT教育模式) 未掌握一些像J2EE等技能型技术是不容易找到一份工作的我们已有同学有这样的教训。从找工作的角度讲，企业关心的不是您学过什么课程，而是关心您能做什么，有什么技能，能做什么项目。</p>
		<p>二、关于嵌入式系统方向 </p>
		<p>嵌入式系统无疑是当前最热门最有发展前途的IT应用领域之一。嵌入式系统用在一些特定专用设备上，通常这些设备的硬件资源(如处理器、存储器等)非常有限，并且对成本很敏感，有时对实时响应要求很高等。特别是随着消费家电的智能化，嵌入式更显重要。像我们平常常见到的手机、PDA、电子字典、可视电话、VCD/DVD/MP3 Player、数字相机(DC)、数字摄像机(DV)、U-Disk、机顶盒(Set Top Box)、高清电视(HDTV)、游戏机、智能玩具、交换机、路由器、数控设备或仪表、汽车电子、家电刂葡低场⒁搅埔瞧鳌⒑教旌娇丈璞傅鹊榷际堑湫偷那度胧较低场?</p>
		<p>嵌入式系统是软硬结合的东西，搞嵌入式开发的人有两类。 </p>
		<p>一类是学电子工程、通信工程等偏硬件专业出身的人，他们主要是搞硬件设计，有时要开发一些与硬件关系最密切的最底层软件，如BootLoader、Board Support Package(像PC的BIOS一样，往下驱动硬件，往上支持操作系统)，最初级的硬件驱动程序等。他们的优势是对硬件原理非常清楚，不足是他们更擅长定义各种硬件接口，但对复杂软件系统往往力不从心(例如嵌入式操作系统原理和复杂应用软件等)。 </p>
		<p>另一类是学软件、计算机专业出身的人，主要从事嵌入式操作系统和应用软件的开发。如果我们学软件的人对硬件原理和接口有较好的掌握，我们完全也可写BSP和硬件驱动程序。嵌入式硬件设计完后，各种功能就全靠软件来实现了，嵌入式设备的增值很大程度上取决于嵌入式软件，这占了嵌入式系统的最主要工作(目前有很多公司将硬件设计包给了专门的硬件公司，稍复杂的硬件都交给台湾或国外公司设计，国内的硬件设计力量很弱，很多嵌入式公司自己只负责开发软件，因为公司都知道，嵌入式产品的差异很大程度在软件上，在软件方面是最有“花头“可做的)，所以我们搞软件的人完全不用担心我们在嵌入式市场上的用武之地，越是智能设备越是复杂系统，软件越起关键作用，而且这是目前的趋势。 </p>
		<p>从事嵌入式软件开发的好处是: </p>
		<p>(1) 目前国内外这方面的人都很稀缺。一方面，是因为这一领域入门门槛较高，不仅要懂较底层软件(例如操作系统级、驱动程序级软件)，对软件专业水平要求较高(嵌入式系统对软件设计的时间和空间效率要求较高)，而且必须懂得硬件的工作原理，所以非专业IT人员很难切入这一领域另一方面，是因为这一领域较新，目前发展太快，很多软硬件技术出现时间不长或正在出现(如ARM处理器、嵌入式操作系统、MPEG技术、无线通信协议等)，掌握这些新技术的人当然很找。嵌入式人才稀缺，身价自然就高，越有经验价格就越高。其实嵌入式人才稀少根本原因可能是大多数人无条件接触这需要相应的嵌入式开发板和软件另外需要有经验的人进行指导开发流程。 </p>
		<p>(2) 与企业计算等应用软件不同，嵌入式领域人才的工作强度通常低一些(但收入不低)。搞企业应用软件的IT企业，这个用户的系统搞完了，又得去搞下一个用户的，而且每个用户的需求和完成时间都得按客户要求改变，往往疲于奔命，重复劳动。相比而言，搞嵌入式系统的公司，都有自己的产品计划，按自己的节奏行事。所开发的产品通常是通用的，不会因客户的不同而修改。一个产品型号开发完了，往往有较长一段空闲时间(或只是对软件进行一些小修补)，有时间进行充电和休整。另外，从事嵌入式软件的每个人工作范围相对狭窄，所涉及的专业技术范围就是那些(ARM、RTOS、MPEG、802.11等)，时间长了这些东西会越搞越有经验，卖卖老本，几句指导也够让那些初入道者琢磨半年的。若搞应用软件，可能下一个客户要换成一个完全不同的软件开发平台，那就苦了。 </p>
		<p>(3) 哪天若想创业，搞自已的产品，那么嵌入式是一个不错的主意，这可不像应用软件那样容易被盗版。土木学院有一个叫启明星的公司开发出一个好象叫“工程e”的掌上PDA，施工技术人员用该PDA可当场进行土木概预算和其它土木计算，据说销路特好。我认识的某大学老师，他开发的饭馆用的点菜PDA(WinCE平台，可无线连网和上网)，据他说销路不错，饭馆点点PDA让客户点菜，多显派头档次。当年有一组同学在学Windows程序设计课程时用VC设计了一个功能很强的点菜系统做为课程项目，当时真想建议他们将这个软件做成PDA，估计会有些销路(上海火车站南广场的Macdonald便使用很漂亮的PDA给用户点食品，像摸像样的)。这些PDA的硬件设计一般都是请其它公司给订做(这叫“贴牌”:OEM)，都是通用的硬件，我们只管设计软件就变成自己的产品了。 </p>
		<p>从事嵌入式软件开发的缺点是: </p>
		<p>(1) 入门起点较高，所用到的技术往往都有一定难度，若软硬件基础不好，特别是操作系统级软件功底不深，则可能不适于此行。 </p>
		<p>(2) 这方面的企业数量要远少于企业计算类企业。特别是从事嵌入式的小企业数量较多(小企业要搞自己的产品创业)，知名大公司较少(搞嵌入式的大公司主要有Intel、Motorola、TI、Philip、Samsung、Sony、Futjtum、Bell-Alcatel、意法半导体、Microtek、研华、华为、中兴通信、上广电等制造类企业)。这些企业的习惯思维方式是到电子、通信等偏硬专业找人。由于正规高校软件学院以前毕业生以企业计算为主，所以正规高校软件学院与这些企业联系相对较少。正规高校软件学院正积极努力，目前已与其中部分公司建立了联系，争取今后能有正规高校软件学院同学到这些企业中实习或就业。 </p>
		<p>(3) 有少数公司经常要硕士以上的人搞嵌入式，主要是基于嵌入式的难度。但大多数公司也并无此要求，只要有经验即可。 </p>
		<p>正规高校软件学院同学若学习嵌入式，显然应偏重于嵌入式软件，特别是嵌入式操作系统方面，应是我们的强项。对于搞嵌入式软件的人，最重要的技术显然是(实际上很多公司的招聘广告上就是这样写的): </p>
		<p>(1) 掌握主流嵌入式微处理器的结构与原理 </p>
		<p>(2) 必须掌握一个嵌入式操作系统 </p>
		<p>(3) 必须熟悉嵌入式软件开发流程并至少做过一个嵌入式软件项目。 </p>
		<p>正规高校软件学院在嵌入式软件方面最重要的课程包括: </p>
		<p>(1) 嵌入式微处理器结构与应用:这是一门嵌入式硬件基础课程，正规高校软件学院用这门课取代了传统的“微机原理与接口”课程(目前国内已有少部分高校IT专业这样做了，因为讲x86微机原理与接口很难找到实际用处，只为教学而已)。我们说过，嵌入式是软硬件结合的技术，搞嵌入式软件的人应对ARM处理器工作原理和接口技术有充分了解，包括ARM的汇编指令系统。</p>
		<p>若不了解处理器原理，怎么能控制硬件工作，怎么能写出节省内存又运行高速的最优代码(嵌入式软件设计特别讲究时空效率)，怎么能写出驱动程序(驱动程序都是与硬件打交道的)很多公司招聘嵌入式软件人员时都要求熟悉ARM处理器，将来若同学到公司中从事嵌入式软件开发，公司都会给你一本该设备的硬件规格说明书 (xxx Specification)，您必须能看懂其中的内存分布和端口使用等最基本的说明(就像x86汇编一样)，否则怎么设计软件。有些同学觉得嵌入式处理器课程较枯燥，这主要是硬件课程都较抽象的原因，等我们的嵌入式实验室10月份建好后，您做了一些实验后就会觉得看得见摸得着。还有同学对ARM汇编不感兴趣，以为嵌入式开发用C语言就足够了。其实不应仅是将汇编语言当成一个程序设计语言，学汇编主要是为了掌握处理器工作原理的。一个不熟悉汇编语言的人，怎么能在该处理器写出最优的C语言代码。</p>
		<p>在嵌入式开发的一些关键部分，有时还必须写汇编，如Bootloader等(可能还包括BSP)。特别是在对速度有极高要求的场合(如DSP处理器的高速图像采集和图像解压缩)，目前主要还要靠汇编写程序(我看到过很多公司是这样做的)。当您在一个嵌入式公司工作时，在查看描述原理的手册时，可能很多都是用汇编描述的(我就遇到过)，这是因为很多硬件设计人员只会写或者喜欢用汇编描述，此时您就必须看懂汇编程序，否则软硬件人员可能就无法交流。很多嵌入式职位招聘时都要求熟悉汇编。 </p>
		<p>(2) 嵌入式操作系统类课程 </p>
		<p>除了WinCE的实时性稍差外，大多数嵌入式操作系统的实时性都很强所以也可称为实时操作系统Real Time Operating System.从事嵌入式的人至少须掌握一个嵌入式操作系统(当然掌握两个更好)这在嵌入式的所有技术中是最为关键的了。目前最重要的RTOS主要包括: </p>
		<p>第一类、传统的经典RTOS:最主要的便是 Vxworks 操作系统，以及其Tornado开发平台。Vxworks因出现稍早，实时性很强(据说可在1ms内响应外部事件请求)，并且内核可极微(据说最小可8K)，可靠性较高等，所以在北美，Vxworks占据了嵌入式系统的多半疆山。特别是在通信设备等实时性要求较高的系统中，几乎非Vxworks莫属。Vxworks的很多概念和技术都和Linux很类似，主要是C语言开发。像Bell-alcatel、Lucent、华为等通信企业在开发产品时，Vxworks用得很多。但Vxworks因价格很高，所以一些小公司或小产品中往往用不起。目前很多公司都在往嵌入式Linux转(听说华为目前正在这样转)。但无论如何，Vxworks在一段长时间内仍是不可动摇的。与Vxworks类似的稍有名的实时操作系统还有pSOS、QNX、Nucleus等RTOS。 </p>
		<p>第二类、嵌入式 Linux 操作系统:Linux的前途除作为服务器操作系统外，最成功的便是在嵌入式领域的应用，原因当然是免费、开源、支持软件多、呼拥者众，这样嵌入式产品成本会低。Linux本身不是一个为嵌入式设计的操作系统，不是微内核的，并且实时性不强。目前应用在嵌入式领域的Linux系统主要有两类:一类是专为嵌入式设计的已被裁减过的Linux系统，最常用的是uClinux(不带MMU功能)，目前占较大应用份额，可在ARM7上跑另一类是跑在ARM 9上的，一般是将Linux 2.4.18内核移植在其上，可使用更多的Linux功能(当然uClinux更可跑在ARM 9上)。</p>
		<p>很多人预测，嵌入式Linux预计将占嵌入式操作系统的50以上份额，非常重要。缺点是熟悉Linux的人太少，开发难度稍大。另外，目前我们能发现很多教材和很多大学都以ucOS/II为教学用实时操作系统，这主要是由于ucOS/II较简单，且开源，非常适合入门者学习实时操作系统原理，但由于ucOS/II功能有限，实用用得较少，所以正规高校软件学院不将其作为教学重点，要学习就应学直接实用的，比如 uClinux就很实用。况且熟悉了Linux开发，不仅在嵌入式领域有用，对开发Linux应用软件，对加深操作系统的认识也有帮助，可谓一举多得。据我所知，目前Intel、Philip都在大搞ARMLINUX的嵌入式开发，Fujitum则是在自己的处理器上大搞Linux开发。目前在嵌入式Linux领域，以下几个方面的人特别难找，一是能将Linux移植到某个新型号的开发版上二是能写Linux驱动程序的人三是熟悉Linux内核裁减和优化的人。正规高校软件学院在该嵌入式Linux方面的课程系列是:本科生操作系统必修课，然后是Linux程序设计选修课，最后是嵌入式Linux系统选修课。正规高校软件学院在Linux方面目前已有较强力量，魏老师和张老师熟悉Linux开发，金老师和唐老师熟悉Linux系统管理。 </p>
		<p>第三类、 Windows CE 嵌入式操作系统:Microsoft也看准了嵌入式的巨大市场，MS永远是最厉害的，WinCE出来只有几年时间，但目前已占据了很大市场份额，特别是在PDA、手机、显示仪表等界面要求较高或者要求快速开发的场合，WinCE目前已很流行(据说有一家卖工控机的公司板子卖得太好，以至来不及为客户裁减WinCE)。WinCE目前主要为4.2版(.NET)，开发平台主要为WinCE Platform Builder，有时也用EVC环境开发一些较上层的应用，由于WinCE开发都是大家熟悉的VC环境，所以正规高校软件学院学过Windows程序设计课程的同学都不会有多大难度，这也是WinCE容易被人们接受的原因，开发环境方便快速，微软的强大技术支持，WinCE开发难度远低于嵌入式Linux。</p>
		<p>对于急于完成，不想拿嵌入式Linux冒险的开发场合，WinCE是最合适了(找嵌入式Linux的人可没那么好找的)，毕竟公司不能像学生学习那样试试看，保证开发成功更重要。根据不同的侧重点 ，WinCE还有两个特殊版本，一个是MS PocketPC操作系统专用于PDA上(掌上电脑)，另一个是MS SmartPhone操作系统用于智能手机上(带PDA功能的手机)，两者也都属于WinCE平台。</p>
		<p>在PDA和手机市场上，除WinCE外，著名的PDA嵌入式操作系统还有Palm OS(因出现很早，很有名)、Symbian 等，但在WinCE的强劲冲击下，Palm和Symbian来日还能有多长正规高校软件学院可能是全国高校中唯一一家开设专门的“Windows CE嵌入式操作系统“课程的学校，这主要是基于以下原因:正规高校软件学院本身前面便有Windows程序设计课程，同学学过VC后再学WinCE非常方便自然，通过学习WinCE同样也可了解嵌入式软件的一般开发过程，对Linux有惧怕心理的同学也很合适。</p>
		<p>　　很显然，嵌入式Linux永远不可能替代WinCE，而且将来谁占份额大还很难讲，毕竟很多人更愿意接受MS的平台，就像各国政府都在大力推LINUX已好长时间，但您能看到几个在PC机上真正使用LINUX的用户据我观察目前在嵌入式平台上LINUX是叫得最响但还是WinCE实际用得更多.嵌入式LINUX可能更多地是一些有长远产品计划的公司为降低成本而进行长远考虑 二是微软亚洲研究院对正规高校软件学院WinCE课程的支持计划，我们也很希望将来正规高校软件学院能有同学通过微软的面试去实习。WinCE和多媒体(如MPEG技术)是微软亚洲工程院目前做得较多的项目领域之一他们很需要精通WinCE的人。 </p>
		<p>总结关于嵌入式操作系统类课程，若您觉得自己功底较深且能钻研下去，则可去学嵌入式Linux若您觉得自己VC功底较好且想短平快地学嵌入式开发，则正规高校软件学院的WinCE课程是最好的选择。 </p>
		<p>(3) 嵌入式开发的其它相关软件课程 </p>
		<p>搞嵌入式若能熟悉嵌入式应用的一些主要领域，这样的人更受企业欢迎。主要的相关领域包括: </p>
		<p>A、数字图像压缩技术:这是嵌入式最重要最热门的应用领域之一，主要是应掌握MPEG编解码算法和技术，如DVD、MP3、PDA、高精电视、机顶盒等都涉及MPEG高速解码问题。为此，正规高校软件学院已预订了一位能开设数字图像处理课程的博士。 </p>
		<p>B、通信协议及编程技术:这包括传统的TCP/IP协议和热门的无线通信协议。首先，大多数嵌入式设备都要连入局域网或Internet，所以首先应掌握TCP/IP协议及其编程，这是需首要掌握的基本技术其次，无线通信是目前的大趋势，所以掌握无线通信协议及编程也是是很重要的。无结通信协议包括无线局域网通信协议802.11系列，Bluetooth，以及移动通信(如GPRS、GSM、CDMA等)。 </p>
		<p>C、网络与信息安全技术:如加密技术，数字证书CA等。正规高校软件学院有这方面的选修课。 </p>
		<p>D、DSP技术:DSP是Digital Signal Process数字信号处理的意思，DSP处理器通过硬件实现数字信号处理算法，如高速数据采集、压缩、解压缩、通信等。数字信号处理是电子、通信等硬件专业的课程，对于搞软件的人若能了解一下最好。目前DSP人才较缺。如果有信号与系统、数字信号处理等课程基础，对于学习MPEG编解码原理会有很大帮助。 </p>
		<p>(4) 嵌入式开发的相关硬件基础 </p>
		<p>对于软件工程专业的学生，从事嵌入式软件开发，像数字电路、计算机组成原理、嵌入式微处理器结构等硬件课程是较重要的。另外，汇编语言、C/C、数据结构和算法、特别是操作系统等软件基础课也是十分重要的。我们的主要目地是能看懂硬件工作原理，但重点应是在嵌入式软件，特别操作系统级软件，那将是我们的优势。 </p>
		<p>我们的研究生里有些是学电子、通信类专业过来的，有较好的模拟电路和单片机基础，学嵌入式非常合适。嵌入式本身就是从单片机发展过来的，只是单片机不带OS，而现在很多嵌入式应用越来越复杂，以至不得不引入嵌入式操作系统。另外，为追求更高速的信号处理速度，现在在一些速度要求较高的场合，有不少公司是将一些DSP算法，如MPEG压缩解压缩算法等用硬件来实现，这就涉及到HDL数字电路设计技术及其FPGA/IP核实现技术，这方面的人目前市场上也很缺。 </p>
		<p>(5) 题外话 </p>
		<p>另外，能写驱动程序的人目前是非常紧缺的(驱动程序也可归于嵌入式范畴)，包括桌面Windows中的DDK开发环境和WDM驱动程序。公司每时每刻都要推出新产品，每一个新产品出来了，要能被操作系统所使用，是必须写驱动程序的。写驱动程序就必须掌握操作系统(如Windows或Linux)的内部工作原理，还涉及到少量硬件知识，难度较大，所以这方面的人很难找。想成为高手的同学，也可从驱动程序方面获得突破。</p>
		<p>我可说一下自己的经历，三年前我曾短暂地在一家公司写过WinCE驱动程序(正是因为知道这方面的人紧缺，所以才要做这方面的事)，尽管那以前从未做过驱动程序，应聘那个职位时正是看准了公司是很难招聘到这方面的人，既然都找不到人，驱动还得有人做，这正是可能有机会切入这一领域的大好机会。面试时大讲自己写过多少万行汇编程序，对计算机工作原理如何清楚，简历中又写着我曾阅读完两本关于Windows Driver Model的两本英文原版书，写过几个小型的驱动程序练习程序(其实根本没写过，我们的同学将来千万不要像我这样，早练就些过硬功夫，就不至于沦落到我这等地步，就不用像我那样去“欺骗”公司了，我这是一个典型的反面教材)，居然一切都PASS(当然最重要的是笔试和面试问题还说得过去)，这只能说明这一领域找人的困难程度。公司本就未指望找到搞过驱动的人，找个有相关基础的人就算不错了。做了以后，发现也并不是怎样难的。其实搞驱动程序的工作是很舒服的，搞完一个版本就会空一段时间，只有等公司新的芯片推出或新的OS出现后，才需要再去开发新一版驱动，那时有将近一个月时间空闲着在等WinCE .NET Beta版推出，准备将驱动程序升级到CE .NET上，现在在软件学院工作整日忙，无限怀念那段悠闲时光。 </p>
		<p>很巧合，最近本人无意中再次体会到了嵌入式的迷人之处。上周我那用了3年的手机终于不能WORK了。此次更新，除要求有手机常见功能外，最好有MP3功能(现在很多英语听力都有MP3文件)，最好有英汉词典，最好还能读WORD文档。最后选了个满足以上条件的最便宜的手机DOPOD 515(斩了我2.2K，但想想这也算自己对嵌入式事业的支持，这样便也想开了)，算得上最低档的智能手机了。回来一查，手机的about显示，本手机Processor是ARM，其OS是MS Smartphone(即WinCE .NET 4.2)，这么巧合，简直可做为学习嵌入式课程的产品案例了(等我们的WinCE课程开得有声有色后，希望能从微软研究院搞些Smartphone来开发开发)。有OS的手机果然了得，金山词霸、WORD、EXCEL、REGEDIT等居然都有smartphone版的，PC上的MP3、DOC等居然在download时都可被自动转换成smartphone格式，真是爽。完全可用Windows CE自己开发一些需要的程序download到自己的手机上。现在市面销售PDA智能手机火爆，MS总是财源滚滚。但我已发现国产的ARMLINUX手机出现在市面上，价格只1.2K。 </p>
		<p>在GOOGLE网上能搜索太多的关于嵌入式系统的讨论了，我刚发现一个http:www.embyte.com 非常不错，有很多有经验者谈自己的体会投入到其中的论坛中，你会切身感到嵌入式学习的热潮。 </p>
		<p>要么走ARMWinCE，要么走ARMLINUX，要么走ARMVXWORKS。每个搞嵌入式的人都可选一条路，条条大路通罗马。</p>
		<p>三、关于游戏软件方向 </p>
		<p>将游戏软件人才称为数字媒体软件人才可能更好听些，包括游戏软件策划(最缺游戏策划的人)、游戏软件美术设计、游戏软件程序设计等多方面的人才，对软件学院，游戏软件程序设计当然是最合适的了。 </p>
		<p>游戏软件人才的确目前很缺，听说很多游戏软件公司苦于没新人才补充，特别是没有高手补充，不得不相互挖人才，以至将游戏软件人才身价越抬越高。网上说日本教育部刚刚批准成立了日本第一家专门培养四年制游戏软件人才的本科大学。其实国内很多大学，特别是软件学院都有搞游戏软件人才的设想，但目前很少有做成的，主要原因是找不到能上游戏软件课的教师，听说有个学校只能花很大的价钱从Korea找老师来上课，果真缺到此等地步 </p>
		<p>已有很多青少年沉湎于网游而颓废的实例，好在还不至于上升到制造精神鸦片的高度，所以开发游戏软件的人也不必每日惭悔(但开发儿童益智类游戏软件的人是不需惭悔的)，如果想想这是为发展民族软件产业做贡献，那反倒是一件有意义的事情了。不过听一家游戏软件公司的老板讲，搞游戏软件开发是非常辛苦的。 </p>
		<p>若想自己创业，搞搞游戏软件是不错的主意。现在网上网站或公司都在收购游戏软件(特别是手机游戏软件，因为手机游戏用户可选从网站上download到手机上，不像网游那么复杂)，按download次数分成或一次性收购的都有。我们的同学在校期间是否也可发点小财搞得好，说不定可卖到国外网站，直接挣$$$呢。 </p>
		<p>大致游戏分成以下几类: </p>
		<p>(1) PC类游戏，包括单机和网游。这类游戏开发平台基本上都是基于VC和DitrectX(如DirectShow，DirectDraw，D3D等，DirectX资料可直接到MS网站上查)。DirectX和OpenGL是两个主要的图形标准，OpenGL跨平台(Unix/Windows上都可跑)，尽管很多搞研究的人对OpenGL赞不绝口，将DirectX骂得一文不值，但事实是，在Windows平台上，DirectX是最快最方便的，所以在Windows平台上的游戏还是DirectX当家。 </p>
		<p>(2) 手机游戏:目前手机游戏主要开发平台有两类: </p>
		<p>第一类手机游戏是 J2ME 平台(Java 2 Micro Edition)，J2ME本是为嵌入式平台设计的Java，但由于Java生来就需要Java虚拟机(JVM)来解释，所以在嵌入式产品很少用J2ME(太慢太耗内存)。但在手机游戏中J2ME倒有用武之地，我想这可能主要是Java可跨OS平台的原因，因为手机的OS是千奇百怪的。我对J2ME完全外行，但上次听Square Enix 公司的人说，J2ME与我们同学学过的J2EE还是有较大差别的。据我所知，目前手机中用的较多的是KJava语言，KJava是运行在一种叫K Java Virtual Machine的解释器上(K JVM是SUN早期为演示J2ME在嵌入式系统应用而开发的一个虚拟机)，所以将在K JVM上运行的J2ME叫KJava。尽管SUN说今后不保证支持K JVM，将开发新的更高性能的J2ME虚拟机取而代之，但由于KJava出现较早，很多早期的手机游戏软件都将K JVM假想成J2ME虚拟机的标准了，所以目前有大量的KJava手机游戏软件存在，而且还在用KJava继续开发。特别是日本的手机游戏软件由于开发较早(像叫什么docomi的日本最大的电信运营商手机游戏搞得很火)，多是基于KJava的。所以目前市场上在招聘手机游戏软件人才时，很多要求掌握KJava。有关J2ME请到Sun的网站上找资料。 </p>
		<p>另一类手机游戏是 BREW 平台，BREW是美国高通公司(Qualcomm，CDMA核心技术都是该公司开发的，有无数移动通信技术专利)发明的，据说可编译成二进制代码，那当然快了。主要的开发语言是C/C。但迫于被指责为较封闭的压力，目前Qualcomm已推出BREW平台上的J2ME虚拟机(但可想像那将是怎样慢的速度)。Qualcomm搞定了很多手机制造商签定BREW授权许可协议，最狠的是Qualcomm与中国联通绑在一起大堆基于BREW的手机游戏，所以有些公司招聘时要求掌握BREW也就不奇怪了。 </p>
		<p>去年00级22班毕业答辩时，有一位同学讲的是在公司做的KJava游戏(那是一家日本游戏软件公司)，还一位同学讲的是另一家公司做的BREW游戏，看来不同的公司有不同的选择。将来谁会更火，我估计随着手机硬件资源的不断提高，不会在乎一个JVM的开销，J2ME应更有前途，毕竟它是更开放的。 </p>
		<p>(3) 专用游戏机:如电视游戏，XBOX，PS2等。 </p>
		<p>从著名游戏公司发来的对网游和手机游戏的人才需求，很有代表性。从中我们可看出，游戏公司对人才的需求主要是以下技术: </p>
		<p>(1) 计算机图形学，特别是3D编程与算法，包括DirectX 或 OpenGL。开发平台是 VC/DIRECTX 或 KJAVA。 </p>
		<p>(2) 公司说，手机游戏因手机资源有限，必须对图像进行压缩，所以若有一些图像压缩算法知识比较好。像若能有MPEG压缩算法较好，手机上采用的是比MPEG压缩得更狠的一些特殊算法，但触类旁通。 </p>
		<p>(3) TCP/IP Socket编程是搞网游开发的人必须掌握的。 </p>
		<p>(4) 人工智能知识:复杂游戏可能需要一些AI算法。 </p>
		<p>(5) 网络与信息安全知识: 网游要防外挂。 </p>
		<p>一般游戏公司的网游服务器是基于 Linux 平台的，所以还提出了对游戏服务器端软件工程师的技术需求(精通MSSQL、ORACLE、MYSQL等数据库，精通Linux Programming，特别是Socket编程)。还有对维护游戏、网站人才需求(ASP.NET和数据库)。注意一条，最好有自己的游戏软件作品，若您应聘时能带一个 DirectX 作品，那将有多强的竞争力，所以最重要的是现在就要行动，实践，实践，再实践。</p>
<img src ="http://www.cppblog.com/threesh/aggbug/15264.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/threesh/" target="_blank">Cpp Fans</a> 2006-11-16 22:26 <a href="http://www.cppblog.com/threesh/archive/2006/11/16/15264.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Oracle的入门心得</title><link>http://www.cppblog.com/threesh/archive/2006/11/07/14766.html</link><dc:creator>Cpp Fans</dc:creator><author>Cpp Fans</author><pubDate>Tue, 07 Nov 2006 01:59:00 GMT</pubDate><guid>http://www.cppblog.com/threesh/archive/2006/11/07/14766.html</guid><wfw:comment>http://www.cppblog.com/threesh/comments/14766.html</wfw:comment><comments>http://www.cppblog.com/threesh/archive/2006/11/07/14766.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/threesh/comments/commentRss/14766.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/threesh/services/trackbacks/14766.html</trackback:ping><description><![CDATA[        Oracle的体系太庞大了，对于初学者来说，难免会有些无从下手的感觉，什么都想学，结果什么都学不好，所以把学习经验共享一下，希望让刚刚入门的人对Oracle有一个总体的认识，少走一些弯路。 
<p><strong>        一、定位</strong></p><p>        Oracle分两大块，一块是开发，一块是管理。开发主要是写写存储过程、触发器什么的，还有就是用Oracle的Develop工具做form。有点类似于程序员，需要有较强的逻辑思维和创造能力，个人觉得会比较辛苦，是青春饭；管理则需要对Oracle数据库的原理有深刻的认识，有全局操纵的能力和紧密的思维，责任较大，因为一个小的失误就会down掉整个数据库，相对前者来说，后者更看重经验。 </p><p>        因为数据库管理的责任重大，很少公司愿意请一个刚刚接触Oracle的人去管理数据库。对于刚刚毕业的年轻人来说，可以先选择做开发，有一定经验后转型，去做数据库的管理。当然，这个还是要看人个的实际情况来定。</p><p><strong>       二、学习方法</strong></p><p>       我的方法很简单，就是：看书、思考、写笔记、做实验、再思考、再写笔记。</p><p>        看完理论的东西，自己静下心来想想，多问自己几个为什么，然后把所学和所想的知识点做个笔记；在想不通或有疑问的时候，就做做实验，想想怎么会这样，同样的，把实验的结果记下来。思考和做实验是为了深入的了解这个知识点。而做笔记的过程，也是理清自己思路的过程。 </p><p>        学习的过程是使一个问题由模糊到清晰，再由清晰到模糊的过程。而每次的改变都代表着你又学到了一个新的知识点。 </p><p>        学习的过程也是从点到线，从线到网，从网到面的过程。当点变成线的时候，你会有总豁然开朗的感觉。当网到面的时候，你就是高手了。</p><p>         很多网友，特别是初学的人，一碰到问题就拿到论坛上来问，在问前，你有没有查过书，自己有没有研究过，有没有搜索一下论坛？这就叫思维惰性。由别人来回答你的问题，会让你在短时间内不费劲地弄懂这个知识点，然而通过自己的努力去研究它，不但会更深入的了解这个知识点，更重要的是在研究的过程会提高你解决问题和分析问题的能力。总的来说，没有钻研的学习态度，不管学什么东西，都不会成功的。 </p><p>        当然，初学的人很多时候是因为遇到问题时，无从下手，也不知道去哪里找资料，才会到论坛上提问题的。但我认为，在提问的时候，是不是可以问别人是如何分析这个问题？从哪里可以找到相关的资料？而不是这个问题的答案是什么？授人以鱼不如授人以渔。</p><p>        下面我讲下我处理问题的过程</p><p>        首先要知道Oracle的官方网站：www.oracle.com 这里有Oracle的各种版本的数据库、应用工具和权威的官方文档。其次，还要知道http://metalink.oracle.com/这里是买了Oracle服务或是oracle的合作伙伴才可以进去的，里面有很多权威的解决方案和补丁。然后就是一些著名网站：asktom.oracle.com www.orafaq.net, www.dbazine.com。这里有很多经验之谈。</p><p>        遇到问题了。如果是概念上的问题，第一时间可以找tahiti.oracle.com，这里会给你最详细的解释。如果在运行的过程中出了什么错误。可以去metalink看看。如果是想知道事务的处理的经验之谈。可以去asktom。当然。这里只是相对而言。</p><p><strong>       三、Oracle的体系</strong><br />        Oracle的体系很庞大，要学习它，首先要了解Oracle的框架。在这里，简要的讲一下Oracle的架构，让初学者对Oracle有一个整体的认识。</p><p>     1、物理结构（由控制文件、数据文件、重做日志文件、参数文件、归档文件、密码文件组成） </p><p>        控制文件：包含维护和验证数据库完整性的必要信息、例如，控制文件用于识别数据文件和重做日志文件，一个数据库至少需要一个控制文件.</p><p>        数据文件：存储数据的文件.</p><p>        重做日志文件：含对数据库所做的更改记录，这样万一出现故障可以启用数据恢复。一个数据库至少需要两个重做日志文件.</p><p>        参数文件：定义Oracle例程的特性，例如它包含调整SGA中一些内存结构大小的参数.</p><p>        归档文件：是重做日志文件的脱机副本，这些副本可能对于从介质失败中进行恢复很必要。 </p><p>       密码文件：认证哪些用户有权限启动和关闭Oracle例程.</p><p><br />        2、逻辑结构（表空间、段、区、块）</p><p>        表空间：是数据库中的基本逻辑结构，一系列数据文件的集合。<br />        段：是对象在数据库中占用的空间.<br />        区：是为数据一次性预留的一个较大的存储空间.<br />        块：ORACLE最基本的存储单位，在建立数据库的时候指定.</p><p><br />       3、内存分配（SGA和PGA）</p><p>        SGA：是用于存储数据库信息的内存区，该信息为数据库进程所共享。它包含Oracle 服务器的数据和控制信息,它是在Oracle服务器所驻留的计算机的实际内存中得以分配，如果实际内存不够再往虚拟内存中写。 </p><p>        PGA：包含单个服务器进程或单个后台进程的数据和控制信息，与几个进程共享的SGA 正相反PGA 是只被一个进程使用的区域，PGA 在创建进程时分配在终止进程时回收.</p><p>        4、后台进程（数据写进程、日志写进程、系统监控、进程监控、检查点进程、归档进程、服务进程、用户进程）</p><p>        数据写进程：负责将更改的数据从数据库缓冲区高速缓存写入数据文件 <br />        日志写进程：将重做日志缓冲区中的更改写入在线重做日志文件 <br />        系统监控：检查数据库的一致性如有必要还会在数据库打开时启动数据库的恢复<br />        进程监控：负责在一个Oracle 进程失败时清理资源 <br />        检查点进程：负责在每当缓冲区高速缓存中的更改永久地记录在数据库中时,更新控制文件和数据文件中的数据库状态信息。 <br />       归档进程：在每次日志切换时把已满的日志组进行备份或归档 <br />       服务进程：用户进程服务。 <br />       用户进程：在客户端，负责将用户的SQL语句传递给服务进程，并从服务器段拿回查询数据。 </p><p>        5、Oracle例程：Oracle例程由SGA内存结构和用于管理数据库的后台进程组成。例程一次只能打开和使用一个数据库。 </p><p>        6、SCN(System ChangeNumber)：系统改变号，一个由系统内部维护的序列号。当系统需要更新的时候自动增加，他是系统中维持数据的一致性和顺序恢复的重要标志。</p><p><strong>       四、深入学习 </strong></p><p>        管理：可以考OCP证书，对Oracle先有一个系统的学习，然后看Oracle Concepts、Oracle online document,对oracle的原理会有更深入的了解，同时可以开始进行一些专题的研究如：RMAN、RAS、STATSPACT、DATAGUARD、TUNING、BACKUP&amp;RECOVER等等。</p><p>        开发：对于想做Oracle开发的，在了解完Oracle基本的体系结构之后，可以重点关注PL/SQL及Oracle的开发工具这一部分。PL/SQL主要是包括怎么写SQL语句，怎么使用Oracle本身的函数，怎么写存储过程、存储函数、触发器等。 Oracle的开发工具主要就是Oracle自己的Developer Suite（Oracle Forms Developer and Reports Developer这些），学会如何熟练使用这些工具。<br /></p><p><br /></p><img src ="http://www.cppblog.com/threesh/aggbug/14766.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/threesh/" target="_blank">Cpp Fans</a> 2006-11-07 09:59 <a href="http://www.cppblog.com/threesh/archive/2006/11/07/14766.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[轉]C语言程序设计基础之文件</title><link>http://www.cppblog.com/threesh/archive/2006/10/27/14273.html</link><dc:creator>Cpp Fans</dc:creator><author>Cpp Fans</author><pubDate>Fri, 27 Oct 2006 03:03:00 GMT</pubDate><guid>http://www.cppblog.com/threesh/archive/2006/10/27/14273.html</guid><wfw:comment>http://www.cppblog.com/threesh/comments/14273.html</wfw:comment><comments>http://www.cppblog.com/threesh/archive/2006/10/27/14273.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/threesh/comments/commentRss/14273.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/threesh/services/trackbacks/14273.html</trackback:ping><description><![CDATA[
		<font size="2">　所谓“文件”是指一组相关数据的有序集合。 这个数据集有一个名称，叫做文件名。 实际上在前面的各章中我们已经多次使用了文件，例如源程序文件、目标文件、可执行文件、库文件 (头文件)等。文件通常是驻留在外部介质(如磁盘等)上的， 在使用时才调入内存中来。从不同的角度可对文件作不同的分类。从用户的角度看，文件可分为普通文件和设备文件两种。 <br /><br />　　普通文件是指驻留在磁盘或其它外部介质上的一个有序数据集，可以是源文件、目标文件、可执行程序； 也可以是一组待输入处理的原始数据，或者是一组输出的结果。对于源文件、目标文件、 可执行程序可以称作程序文件，对输入输出数据可称作数据文件。<br /><br />　　设备文件是指与主机相联的各种外部设备，如显示器、打印机、键盘等。在操作系统中，把外部设备也看作是一个文件来进行管理，把它们的输入、输出等同于对磁盘文件的读和写。 通常把显示器定义为标准输出文件， 一般情况下在屏幕上显示有关信息就是向标准输出文件输出。如前面经常使用的printf,putchar 函数就是这类输出。键盘通常被指定标准的输入文件， 从键盘上输入就意味着从标准输入文件上输入数据。scanf,getchar函数就属于这类输入。 <br /><br />　　从文件编码的方式来看，文件可分为ASCII码文件和二进制码文件两种。<br /><br />　　ASCII文件也称为文本文件，这种文件在磁盘中存放时每个字符对应一个字节，用于存放对应的ASCII码。例如，数5678的存储形式为：<br />ASC码： 　00110101 00110110 00110111 00111000<br />　　　　　↓ 　　　　↓　　　　↓ 　　　↓<br />十进制码： 5　　　　　6　　　　7　　　　8 共占用4个字节。ASCII码文件可在屏幕上按字符显示， 例如源程序文件就是ASCII文件，用DOS命令TYPE可显示文件的内容。 由于是按字符显示，因此能读懂文件内容。<br /><br />　　二进制文件是按二进制的编码方式来存放文件的。 例如， 数5678的存储形式为： 00010110 00101110只占二个字节。二进制文件虽然也可在屏幕上显示， 但其内容无法读懂。C系统在处理这些文件时，并不区分类型，都看成是字符流，按字节进行处理。 输入输出字符流的开始和结束只由程序控制而不受物理符号(如回车符)的控制。 因此也把这种文件称作“流式文件”。<br /><br />　　本章讨论流式文件的打开、关闭、读、写、 定位等各种操作。文件指针在C语言中用一个指针变量指向一个文件， 这个指针称为文件指针。通过文件指针就可对它所指的文件进行各种操作。 定义说明文件指针的一般形式为： FILE* 指针变量标识符； 其中FILE应为大写，它实际上是由系统定义的一个结构， 该结构中含有文件名、文件状态和文件当前位置等信息。 在编写源程序时不必关心FILE结构的细节。例如：FILE *fp； 表示fp是指向FILE结构的指针变量，通过fp 即可找存放某个文件信息的结构变量，然后按结构变量提供的信息找到该文件， 实施对文件的操作。习惯上也笼统地把fp称为指向一个文件的指针。文件的打开与关闭文件在进行读写操作之前要先打开，使用完毕要关闭。 所谓打开文件，实际上是建立文件的各种有关信息， 并使文件指针指向该文件，以便进行其它操作。关闭文件则断开指针与文件之间的联系，也就禁止再对该文件进行操作。<br /><br />　　在C语言中，文件操作都是由库函数来完成的。 在本章内将介绍主要的文件操作函数。<br /><br />　　文件打开函数fopen<br /><br />　　fopen函数用来打开一个文件，其调用的一般形式为： 文件指针名=fopen(文件名，使用文件方式) 其中，“文件指针名”必须是被说明为FILE 类型的指针变量，“文件名”是被打开文件的文件名。 “使用文件方式”是指文件的类型和操作要求。“文件名”是字符串常量或字符串数组。例如： <br /><br /></font>
		<table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1">
				<tbody>
						<tr>
								<td>FILE *fp；<br />fp=("file a","r");</td>
						</tr>
				</tbody>
		</table>
		<br />　　其意义是在当前目录下打开文件file a， 只允许进行“读”操作，并使fp指向该文件。<br /><br />　　又如：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>FILE *fphzk<br />fphzk=("c:\\hzk16',"rb")</td></tr></tbody></table><br />　　其意义是打开C驱动器磁盘的根目录下的文件hzk16， 这是一个二进制文件，只允许按二进制方式进行读操作。两个反斜线“\\ ”中的第一个表示转义字符，第二个表示根目录。使用文件的方式共有12种，下面给出了它们的符号和意义。 <br /><br />文件使用方式 　　　　　　　意 义<br />“rt”　　　　　　只读打开一个文本文件，只允许读数据 <br />“wt”　　　　　　只写打开或建立一个文本文件，只允许写数据<br />“at”　　　　　　追加打开一个文本文件，并在文件末尾写数据<br />“rb”　　　　　　只读打开一个二进制文件，只允许读数据<br />“wb”　　　　 　 只写打开或建立一个二进制文件，只允许写数据<br />“ab” 　　　　 　追加打开一个二进制文件，并在文件末尾写数据<br />“rt+”　　　　　 读写打开一个文本文件，允许读和写<br />“wt+”　　　　　 读写打开或建立一个文本文件，允许读写<br />“at+”　　　　　 读写打开一个文本文件，允许读，或在文件末追加数 据<br />“rb+”　　　　　 读写打开一个二进制文件，允许读和写 <br />“wb+”　　　　　 读写打开或建立一个二进制文件，允许读和写<br />“ab+” 　　　　　读写打开一个二进制文件，允许读，或在文件末追加数据<br /><br />　　对于文件使用方式有以下几点说明：<br /><br />　　1. 文件使用方式由r,w,a,t,b，+六个字符拼成，各字符的含义是：<br /><br />　　r(read): 读<br />　　w(write): 写<br />　　a(append): 追加<br />　　t(text): 文本文件，可省略不写<br />　　b(banary): 二进制文件<br />　　+: 读和写<br /><br />　　2. 凡用“r”打开一个文件时，该文件必须已经存在， 且只能从该文件读出。<br /><br />　　3. 用“w”打开的文件只能向该文件写入。 若打开的文件不存在，则以指定的文件名建立该文件，若打开的文件已经存在，则将该文件删去，重建一个新文件。<br /><br />　　4. 若要向一个已存在的文件追加新的信息，只能用“a ”方式打开文件。但此时该文件必须是存在的，否则将会出错。<br /><br />　　5. 在打开一个文件时，如果出错，fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成打开文件的工作，并作相应的处理。因此常用以下程序段打开文件：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>if((fp=fopen("c:\\hzk16","rb")==NULL)<br />{<br />printf("\nerror on open c:\\hzk16 file!");<br />getch();<br />exit(1);<br />}</td></tr></tbody></table><br />　　这段程序的意义是，如果返回的指针为空，表示不能打开C盘根目录下的hzk16文件，则给出提示信息“error on open c:\ hzk16file!”，下一行getch()的功能是从键盘输入一个字符，但不在屏幕上显示。在这里，该行的作用是等待， 只有当用户从键盘敲任一键时，程序才继续执行， 因此用户可利用这个等待时间阅读出错提示。敲键后执行exit(1)退出程序。<br /><br />　　6. 把一个文本文件读入内存时，要将ASCII码转换成二进制码， 而把文件以文本方式写入磁盘时，也要把二进制码转换成ASCII码，因此文本文件的读写要花费较多的转换时间。对二进制文件的读写不存在这种转换。<br /><br />　　7. 标准输入文件(键盘)，标准输出文件(显示器 )，标准出错输出(出错信息)是由系统打开的，可直接使用。文件关闭函数ｆCｌｏｓｅ文件一旦使用完毕，应用关闭文件函数把文件关闭， 以避免文件的数据丢失等错误。<br /><br />　　fclose函数<br /><br />　　调用的一般形式是： fclose(文件指针)； 例如：<br /><br />　　fclose(fp); 正常完成关闭文件操作时，fclose函数返回值为0。如返回非零值则表示有错误发生。文件的读写对文件的读和写是最常用的文件操作。 <br /><br />　　在C语言中提供了多种文件读写的函数： <br /><br />　　·字符读写函数 ：fgetc和fputc<br /><br />　　·字符串读写函数：fgets和fputs<br /><br />　　·数据块读写函数：freed和fwrite<br /><br />　　·格式化读写函数：fscanf和fprinf<br /><br />　　下面分别予以介绍。使用以上函数都要求包含头文件stdio.h。字符读写函数ｆｇｅｔC和ｆｐｕｔC字符读写函数是以字符(字节)为单位的读写函数。 每次可从文件读出或向文件写入一个字符。<br /><br /><p></p>　　<strong>一、读字符函数fgetc</strong><br /><br />　　fgetc函数的功能是从指定的文件中读一个字符，函数调用的形式为： 字符变量=fgetc(文件指针)； 例如：ch=fgetc(fp);其意义是从打开的文件fp中读取一个字符并送入ch中。<br /><br />　　对于fgetc函数的使用有以下几点说明：<br /><br />　　1. 在fgetc函数调用中，读取的文件必须是以读或读写方式打开的。<br /><br />　　2. 读取字符的结果也可以不向字符变量赋值，例如：fgetc(fp);但是读出的字符不能保存。<br /><br />　　3. 在文件内部有一个位置指针。用来指向文件的当前读写字节。在文件打开时，该指针总是指向文件的第一个字节。使用fgetc 函数后， 该位置指针将向后移动一个字节。 因此可连续多次使用fgetc函数，读取多个字符。 应注意文件指针和文件内部的位置指针不是一回事。文件指针是指向整个文件的，须在程序中定义说明，只要不重新赋值，文件指针的值是不变的。文件内部的位置指针用以指示文件内部的当前读写位置，每读写一次，该指针均向后移动，它不需在程序中定义说明，而是由系统自动设置的。<br /><br />　　[例10.1]读入文件e10-1.c，在屏幕上输出。<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>#include&lt;stdio.h&gt;<br />main()<br />{<br />FILE *fp;<br />char ch;<br />if((fp=fopen("e10_1.c","rt"))==NULL)<br />{<br />printf("Cannot open file strike any key exit!");<br />getch();<br />exit(1);<br />}<br />ch=fgetc(fp);<br />while (ch!=EOF)<br />{<br />putchar(ch);<br />ch=fgetc(fp);<br />}<br />fclose(fp);<br />}</td></tr></tbody></table><br />　　本例程序的功能是从文件中逐个读取字符，在屏幕上显示。 程序定义了文件指针fp,以读文本文件方式打开文件“e10_1.c”， 并使fp指向该文件。如打开文件出错， 给出提示并退出程序。程序第12行先读出一个字符，然后进入循环， 只要读出的字符不是文件结束标志(每个文件末有一结束标志EOF)就把该字符显示在屏幕上，再读入下一字符。每读一次，文件内部的位置指针向后移动一个字符，文件结束时，该指针指向EOF。执行本程序将显示整个文件。<br /><br />　　<strong>二、写字符函数fputc</strong><br /><br />　　fputc函数的功能是把一个字符写入指定的文件中，函数调用的 形式为： fputc(字符量，文件指针)； 其中，待写入的字符量可以是字符常量或变量，例如：fputc('a',fp);其意义是把字符a写入fp所指向的文件中。<br /><br />　　对于fputc函数的使用也要说明几点：<br /><br />　　1. 被写入的文件可以用、写、读写，追加方式打开，用写或读写方式打开一个已存在的文件时将清除原有的文件内容，写入字符从文件首开始。如需保留原有文件内容，希望写入的字符以文件末开始存放，必须以追加方式打开文件。被写入的文件若不存在，则创建该文件。<br /><br />　　2. 每写入一个字符，文件内部位置指针向后移动一个字节。<br /><br />　　3. fputc函数有一个返回值，如写入成功则返回写入的字符， 否则返回一个EOF。可用此来判断写入是否成功。<br /><br />　　[例10.2]从键盘输入一行字符，写入一个文件， 再把该文件内容读出显示在屏幕上。<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>#include&lt;stdio.h&gt;<br />main()<br />{<br />FILE *fp;<br />char ch;<br />if((fp=fopen("string","wt+"))==NULL)<br />{<br />printf("Cannot open file strike any key exit!");<br />getch();<br />exit(1);<br />}<br />printf("input a string:\n");<br />ch=getchar();<br />while (ch!='\n')<br />{<br />fputc(ch,fp);<br />ch=getchar();<br />}<br />rewind(fp);<br />ch=fgetc(fp);<br />while(ch!=EOF)<br />{<br />putchar(ch);<br />ch=fgetc(fp);<br />}<br />printf("\n");<br />fclose(fp);<br />}</td></tr></tbody></table><br />　　程序中第6行以读写文本文件方式打开文件string。程序第13行从键盘读入一个字符后进入循环，当读入字符不为回车符时， 则把该字符写入文件之中，然后继续从键盘读入下一字符。 每输入一个字符，文件内部位置指针向后移动一个字节。写入完毕， 该指针已指向文件末。如要把文件从头读出，须把指针移向文件头， 程序第19行rewind函数用于把fp所指文件的内部位置指针移到文件头。 第20至25行用于读出文件中的一行内容。<br /><br />　　[例10.3]把命令行参数中的前一个文件名标识的文件， 复制到后一个文件名标识的文件中， 如命令行中只有一个文件名则把该文件写到标准输出文件(显示器)中。<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>#include&lt;stdio.h&gt;<br />main(int argc,char *argv[])<br />{<br />FILE *fp1,*fp2;<br />char ch;<br />if(argc==1)<br />{<br />printf("have not enter file name strike any key exit");<br />getch();<br />exit(0);<br />}<br />if((fp1=fopen(argv[1],"rt"))==NULL)<br />{<br />printf("Cannot open %s\n",argv[1]);<br />getch();<br />exit(1);<br />}<br />if(argc==2) fp2=stdout;<br />else if((fp2=fopen(argv[2],"wt+"))==NULL)<br />{<br />printf("Cannot open %s\n",argv[1]);<br />getch();<br />exit(1);<br />}<br />while((ch=fgetc(fp1))!=EOF)<br />fputc(ch,fp2);<br />fclose(fp1);<br />fclose(fp2);<br />}</td></tr></tbody></table><br />　　本程序为带参的main函数。程序中定义了两个文件指针 fp1 和fp2，分别指向命令行参数中给出的文件。如命令行参数中没有给出文件名，则给出提示信息。程序第18行表示如果只给出一个文件名，则使fp2指向标准输出文件(即显示器)。程序第25行至28行用循环语句逐个读出文件1中的字符再送到文件2中。再次运行时，给出了一个文件名(由例10.2所建立的文件)， 故输出给标准输出文件stdout，即在显示器上显示文件内容。第三次运行，给出了二个文件名，因此把string中的内容读出，写入到OK之中。可用DOS命令type显示OK的内容：<br /><br /><p></p>　　<strong>字符串读写函数fgets和fputs</strong><br /><br />　　一、读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符数组中，函数调用的形式为： fgets(字符数组名，n，文件指针)； 其中的n是一个正整数。表示从文件中读出的字符串不超过 n-1个字符。在读入的最后一个字符后加上串结束标志'\0'。例如：fgets(str,n,fp);的意义是从fp所指的文件中读出n-1个字符送入字符数组str中。<br /><br />　　[例10.4]从e10_1.c文件中读入一个含10个字符的字符串。<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>#include&lt;stdio.h&gt;<br />main()<br />{<br />FILE *fp;<br />char str[11];<br />if((fp=fopen("e10_1.c","rt"))==NULL)<br />{<br />printf("Cannot open file strike any key exit!");<br />getch();<br />exit(1);<br />}<br />fgets(str,11,fp);<br />printf("%s",str);<br />fclose(fp);<br />}</td></tr></tbody></table><br />　　本例定义了一个字符数组str共11个字节，在以读文本文件方式打开文件e101.c后，从中读出10个字符送入str数组，在数组最后一个单元内将加上'\0'，然后在屏幕上显示输出str数组。输出的十个字符正是例10.1程序的前十个字符。<br /><br />　　对fgets函数有两点说明：<br /><br />　　1. 在读出n-1个字符之前，如遇到了换行符或EOF，则读出结束。<br /><br />　　2. fgets函数也有返回值，其返回值是字符数组的首地址。<br /><br />　　二、写字符串函数fputs<br /><br />　　fputs函数的功能是向指定的文件写入一个字符串，其调用形式为： fputs(字符串，文件指针) 其中字符串可以是字符串常量，也可以是字符数组名， 或指针 变量，例如：<br /><br />fputs(“abcd“，fp)；<br /><br />　　其意义是把字符串“abcd”写入fp所指的文件之中。[例10.5]在例10.2中建立的文件string中追加一个字符串。<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>#include&lt;stdio.h&gt;<br />main()<br />{<br />FILE *fp;<br />char ch,st[20];<br />if((fp=fopen("string","at+"))==NULL)<br />{<br />printf("Cannot open file strike any key exit!");<br />getch();<br />exit(1);<br />}<br />printf("input a string:\n");<br />scanf("%s",st);<br />fputs(st,fp);<br />rewind(fp);<br />ch=fgetc(fp);<br />while(ch!=EOF)<br />{<br />putchar(ch);<br />ch=fgetc(fp);<br />}<br />printf("\n");<br />fclose(fp);<br />}</td></tr></tbody></table><br />　　本例要求在string文件末加写字符串，因此，在程序第6行以追加读写文本文件的方式打开文件string 。 然后输入字符串， 并用fputs函数把该串写入文件string。在程序15行用rewind函数把文件内部位置指针移到文件首。 再进入循环逐个显示当前文件中的全部内容。<br /><br /><p></p>　　<strong>数据块读写函数fread和fwrite</strong><br /><br />　　C语言还提供了用于整块数据的读写函数。 可用来读写一组数据，如一个数组元素，一个结构变量的值等。读数据块函数调用的一般形式为： fread(buffer,size,count,fp); 写数据块函数调用的一般形式为： fwrite(buffer,size,count,fp); 其中buffer是一个指针，在fread函数中，它表示存放输入数据的首地址。在fwrite函数中，它表示存放输出数据的首地址。 size 表示数据块的字节数。count 表示要读写的数据块块数。fp 表示文件指针。<br /><br />　　例如：<br /><br />fread(fa,4,5,fp); 其意义是从fp所指的文件中，每次读4个字节(一个实数)送入实数组fa中，连续读5次，即读5个实数到fa中。<br /><br />　　[例10.6]从键盘输入两个学生数据，写入一个文件中， 再读出这两个学生的数据显示在屏幕上。<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>#include&lt;stdio.h&gt;<br />struct stu<br />{<br />char name[10];<br />int num;<br />int age;<br />char addr[15];<br />}boya[2],boyb[2],*pp,*qq;<br />main()<br />{<br />FILE *fp;<br />char ch;<br />int i;<br />pp=boya;<br />qq=boyb;<br />if((fp=fopen("stu_list","wb+"))==NULL)<br />{<br />printf("Cannot open file strike any key exit!");<br />getch();<br />exit(1);<br />}<br />printf("\ninput data\n");<br />for(i=0;i&lt;2;i++,pp++)<br />scanf("%s%d%d%s",pp-&gt;name,&amp;pp-&gt;num,&amp;pp-&gt;age,pp-&gt;addr);<br />pp=boya;<br />fwrite(pp,sizeof(struct stu),2,fp);<br />rewind(fp);<br />fread(qq,sizeof(struct stu),2,fp);<br />printf("\n\nname\tnumber age addr\n");<br />for(i=0;i&lt;2;i++,qq++)<br />printf("%s\t%5d%7d%s\n",qq-&gt;name,qq-&gt;num,qq-&gt;age,qq-&gt;addr);<br />fclose(fp);<br />}</td></tr></tbody></table><br />　　本例程序定义了一个结构stu,说明了两个结构数组boya和 boyb以及两个结构指针变量pp和qq。pp指向boya,qq指向boyb。程序第16行以读写方式打开二进制文件“stu_list”，输入二个学生数据之后，写入该文件中， 然后把文件内部位置指针移到文件首，读出两块学生数据后，在屏幕上显示。<br /><br /><p></p>　　<strong>格式化读写函数fscanf和fprintf</strong><br /><br />　　fscanf函数，fprintf函数与前面使用的scanf和printf 函数的功能相似，都是格式化读写函数。 两者的区别在于 fscanf 函数和fprintf函数的读写对象不是键盘和显示器，而是磁盘文件。这两个函数的调用格式为： fscanf(文件指针，格式字符串，输入表列)； fprintf(文件指针，格式字符串，输出表列)； 例如：<br /><br />　　fscanf(fp,"%d%s",&amp;i,s);<br />　　fprintf(fp,"%d%c",j,ch); <br /><br />　　用fscanf和fprintf函数也可以完成例10.6的问题。修改后的程序如例10.7所示。<br /><br />　　[例10.7]<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>#include&lt;stdio.h&gt;<br />struct stu<br />{<br />char name[10];<br />int num;<br />int age;<br />char addr[15];<br />}boya[2],boyb[2],*pp,*qq;<br />main()<br />{<br />FILE *fp;<br />char ch;<br />int i;<br />pp=boya;<br />qq=boyb;<br />if((fp=fopen("stu_list","wb+"))==NULL)<br />{<br />printf("Cannot open file strike any key exit!");<br />getch();<br />exit(1);<br />}<br />printf("\ninput data\n");<br />for(i=0;i&lt;2;i++,pp++)<br />scanf("%s%d%d%s",pp-&gt;name,&amp;pp-&gt;num,&amp;pp-&gt;age,pp-&gt;addr);<br />pp=boya;<br />for(i=0;i&lt;2;i++,pp++)<br />fprintf(fp,"%s %d %d %s\n",pp-&gt;name,pp-&gt;num,pp-&gt;age,pp-&gt;<br />addr);<br />rewind(fp);<br />for(i=0;i&lt;2;i++,qq++)<br />fscanf(fp,"%s %d %d %s\n",qq-&gt;name,&amp;qq-&gt;num,&amp;qq-&gt;age,qq-&gt;addr);<br />printf("\n\nname\tnumber age addr\n");<br />qq=boyb;<br />for(i=0;i&lt;2;i++,qq++)<br />printf("%s\t%5d %7d %s\n",qq-&gt;name,qq-&gt;num, qq-&gt;age,<br />qq-&gt;addr);<br />fclose(fp);<br />}</td></tr></tbody></table><br />　　与例10.6相比，本程序中fscanf和fprintf函数每次只能读写一个结构数组元素，因此采用了循环语句来读写全部数组元素。 还要注意指针变量pp,qq由于循环改变了它们的值，因此在程序的25和32行分别对它们重新赋予了数组的首地址。<br /><br />　　文件的随机读写<br /><br />　　前面介绍的对文件的读写方式都是顺序读写， 即读写文件只能从头开始，顺序读写各个数据。 但在实际问题中常要求只读写文件中某一指定的部分。 为了解决这个问题可移动文件内部的位置指针到需要读写的位置，再进行读写，这种读写称为随机读写。 实现随机读写的关键是要按要求移动位置指针，这称为文件的定位。文件定位移动文件内部位置指针的函数主要有两个， 即 rewind 函数和fseek函数。<br /><br />　　rewind函数前面已多次使用过，其调用形式为： rewind(文件指针)； 它的功能是把文件内部的位置指针移到文件首。 下面主要介绍<br />fseek函数。<br /><br />　　fseek函数用来移动文件内部位置指针，其调用形式为： fseek(文件指针，位移量，起始点)； 其中：“文件指针”指向被移动的文件。 “位移量”表示移动的字节数，要求位移量是long型数据，以便在文件长度大于64KB 时不会出错。当用常量表示位移量时，要求加后缀“L”。“起始点”表示从何处开始计算位移量，规定的起始点有三种：文件首，当前位置和文件尾。<br /><br />　　其表示方法如表10.2。 <br /><br />起始点 　　　表示符号 　　　数字表示<br />──────────────────────────<br />文件首 　　　SEEK—SET　　　　0<br />当前位置 　　SEEK—CUR　　　　1<br />文件末尾 　　SEEK—END 　　　 2<br /><br />　　例如：<br /><br />　　fseek(fp,100L,0);其意义是把位置指针移到离文件首100个字节处。还要说明的是fseek函数一般用于二进制文件。在文本文件中由于要进行转换，故往往计算的位置会出现错误。文件的随机读写在移动位置指针之后， 即可用前面介绍的任一种读写函数进行读写。由于一般是读写一个数据据块，因此常用fread和fwrite函数。下面用例题来说明文件的随机读写。<br /><br />　　[例10.8]在学生文件stu list中读出第二个学生的数据。<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>#include&lt;stdio.h&gt;<br />struct stu<br />{<br />　char name[10];<br />　int num;<br />　int age;<br />　char addr[15];<br />}boy,*qq;<br />main()<br />{<br />　FILE *fp;<br />　char ch;<br />　int i=1;<br />　qq=&amp;boy;<br />　if((fp=fopen("stu_list","rb"))==NULL)<br />　{<br />　　printf("Cannot open file strike any key exit!");<br />　　getch();<br />　　exit(1);<br />　}<br />　rewind(fp);<br />　fseek(fp,i*sizeof(struct stu),0);<br />　fread(qq,sizeof(struct stu),1,fp);<br />　printf("\n\nname\tnumber age addr\n");<br />　printf("%s\t%5d %7d %s\n",qq-&gt;name,qq-&gt;num,qq-&gt;age,<br />　qq-&gt;addr);<br />}</td></tr></tbody></table><br />　　文件stu_list已由例10.6的程序建立，本程序用随机读出的方法读出第二个学生的数据。程序中定义boy为stu类型变量，qq为指向boy的指针。以读二进制文件方式打开文件，程序第22行移动文件位置指针。其中的i值为1，表示从文件头开始，移动一个stu类型的长度， 然后再读出的数据即为第二个学生的数据。<br /><br />　　文件检测函数<br /><br />　　C语言中常用的文件检测函数有以下几个。<br /><br />　　一、文件结束检测函数feof函数调用格式： feof(文件指针)； <br /><br />　　功能：判断文件是否处于文件结束位置，如文件结束，则返回值为1，否则为0。<br /><br />　　二、读写文件出错检测函数ferror函数调用格式： ferror(文件指针)； <br /><br />　　功能：检查文件在用各种输入输出函数进行读写时是否出错。 如ferror返回值为0表示未出错，否则表示有错。<br /><br />　　三、文件出错标志和文件结束标志置0函数clearerr函数调用格式： clearerr(文件指针); <br /><br />　　功能：本函数用于清除出错标志和文件结束标志，使它们为0值。<br /><br />　　C库文件<br /><br />　　C系统提供了丰富的系统文件，称为库文件，C的库文件分为两类，一类是扩展名为".h"的文件，称为头文件， 在前面的包含命令中我们已多次使用过。在".h"文件中包含了常量定义、 类型定义、宏定义、函数原型以及各种编译选择设置等信息。另一类是函数库，包括了各种函数的目标代码，供用户在程序中调用。 通常在程序中调用一个库函数时，要在调用之前包含该函数原型所在的".h" 文件。<br /><br />　　在附录中给出了全部库函数。<br /><br />ALLOC.H 　　　说明内存管理函数(分配、释放等)。<br />ASSERT.H 　 　定义 assert调试宏。<br />BIOS.H 　　 　说明调用IBM—PC ROM BIOS子程序的各个函数。<br />CONIO.H 　　　说明调用DOS控制台I/O子程序的各个函数。<br />CTYPE.H 　　　包含有关字符分类及转换的名类信息(如 isalpha和toascii等)。<br />DIR.H 　　　　包含有关目录和路径的结构、宏定义和函数。<br />DOS.H 　　　　定义和说明MSDOS和8086调用的一些常量和函数。<br />ERRON.H 　　　定义错误代码的助记符。<br />FCNTL.H 　　　定义在与open库子程序连接时的符号常量。<br />FLOAT.H 　　　包含有关浮点运算的一些参数和函数。<br />GRAPHICS.H 　 说明有关图形功能的各个函数，图形错误代码的常量定义，正对不同驱动程序的各种颜色值，及函数用到的一些特殊结构。<br />IO.H 　　　　 包含低级I/O子程序的结构和说明。<br />LIMIT.H 　　　包含各环境参数、编译时间限制、数的范围等信息。<br />MATH.H 　　　 说明数学运算函数，还定了 HUGE VAL 宏， 说明了matherr和matherr子程序用到的特殊结构。<br />MEM.H 　　　　说明一些内存操作函数(其中大多数也在STRING.H 中说明)。<br />PROCESS.H 　　说明进程管理的各个函数，spawn…和EXEC …函数的结构说明。<br />SETJMP.H 　　 定义longjmp和setjmp函数用到的jmp buf类型， 说明这两个函数。<br />SHARE.H 　　　定义文件共享函数的参数。<br />SIGNAL.H 　　 定义SIG[ZZ(Z] [ZZ)]IGN和SIG[ZZ(Z] [ZZ)]DFL常量，说明rajse和signal两个函数。<br />STDARG.H 　　 定义读函数参数表的宏。(如vprintf,vscarf函数)。<br />STDDEF.H 　　 定义一些公共数据类型和宏。<br />STDIO.H 　　　定义Kernighan和Ritchie在Unix System V 中定义的标准和扩展的类型和宏。还定义标准I/O 预定义流：stdin,stdout和stderr，说明 I/O流子程序。<br />STDLIB.H 　　 说明一些常用的子程序：转换子程序、搜索/ 排序子程序等。<br />STRING.H 　　 说明一些串操作和内存操作函数。<br />SYS\STAT.H 　 定义在打开和创建文件时用到的一些符号常量。<br />SYS\TYPES.H 　说明ftime函数和timeb结构。<br />SYS\TIME.H 　 定义时间的类型time[ZZ(Z] [ZZ)]t。<br />TIME.H 　　　 定义时间转换子程序asctime、localtime和gmtime的结构，ctime、 difftime、 gmtime、 localtime和stime用到的类型，并提供这些函数的原型。<br />VALUE.H 　　　定义一些重要常量， 包括依赖于机器硬件的和为与Unix System V相兼容而说明的一些常量，包括浮点和双精度值的范围。<br /><img src ="http://www.cppblog.com/threesh/aggbug/14273.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/threesh/" target="_blank">Cpp Fans</a> 2006-10-27 11:03 <a href="http://www.cppblog.com/threesh/archive/2006/10/27/14273.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>