??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲AV中文无码乱人伦下载,亚洲免费观看在线视频,91在线精品亚洲一区二区http://m.tkk7.com/shooper/category/10934.htmlBeginning Javazh-cnFri, 02 Mar 2007 07:22:08 GMTFri, 02 Mar 2007 07:22:08 GMT60java中的易؜问题攉 http://m.tkk7.com/shooper/articles/49130.htmlShooper.JavaShooper.JavaTue, 30 May 2006 15:13:00 GMThttp://m.tkk7.com/shooper/articles/49130.htmlhttp://m.tkk7.com/shooper/comments/49130.htmlhttp://m.tkk7.com/shooper/articles/49130.html#Feedback0http://m.tkk7.com/shooper/comments/commentRss/49130.htmlhttp://m.tkk7.com/shooper/services/trackbacks/49130.html
final?修饰W(关键字)如果一个类被声明ؓfinalQ意味着它不能再z出新的子c,不能作ؓ父类被ѝ因此一个类不能既被声明?abstract的,又被声明为final的。将变量或方法声明ؓfinalQ可以保证它们在使用中不被改变。被声明为final的变量必d声明时给定初|而在以后的引用中只能dQ不可修攏V被声明为final的方法也同样只能使用Q不能重?

finally?再异常处理时提供 finally 块来执行M清除操作。如果抛Z个异常,那么相匹配的 catch 子句׃执行Q然后控制就会进?finally 块(如果有的话)?
finalize?Ҏ名。Java 技术允怋?finalize() Ҏ在垃圾收集器对象从内存中清除出M前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对q个对象调用的。它是在 Object cM定义的,因此所有的c都l承了它。子c覆?finalize() Ҏ以整理系l资源或者执行其他清理工作。finalize() Ҏ是在垃圾攉器删除对象之前对q个对象调用的?

W二QAnonymous Inner Class (匿名内部c? 是否可以extends(l承)其它c,是否可以implements(实现)interface(接口)?

匿名的内部类是没有名字的内部cR不能extends(l承) 其它c,但一个内部类可以作ؓ一个接口,由另一个内部类实现?

W三QStatic Nested Class ?Inner Class的不同,说得多好
Nested Class Q一般是C++的说法)QInner Class (一般是JAVA的说?。Java内部cMC++嵌套cL大的不同在于是否有指向外部的引用上。具体可见http: //www.frontfree.net/articles/services/view.asp?id=704&page=1
注: 静态内部类QInner ClassQ意味着1创徏一个static内部cȝ对象Q不需要一个外部类对象Q?不能从一个static内部cȝ一个对象访问一个外部类对象

W四Q?amp;?amp;&的区别?
&是位q算W?amp;&是布逻辑q算W?

W五QHashMap和Hashtable的区别?
都属于Map接口的类Q实C惟一键映到特定的g?
HashMap cL有分cL者排序。它允许一?null 键和多个 null 倹{?
Hashtable cM?HashMapQ但是不允许 null 键和 null 倹{它也比 HashMap 慢,因ؓ它是同步的?

W六QCollection ?Collections的区别?
Collections是个java.util下的c,它包含有各种有关集合操作的静态方法?
Collection是个java.util下的接口Q它是各U集合结构的父接口?


W七Q什么时候用assert?
断言是一个包含布表辑ּ的语句,在执行这个语句时假定该表辑ּ?true。如果表辑ּ计算?falseQ那么系l会报告一?Assertionerror。它用于调试目的Q?
assert(a > 0); // throws an Assertionerror if a <= 0
断言可以有两UŞ式:
assert Expression1 ;
assert Expression1 : Expression2 ;
Expression1 应该L产生一个布倹{?
Expression2 可以是得Z个值的L表达式。这个值用于生成显C更多调试信息的 String 消息?
断言在默认情况下是禁用的。要在编译时启用断言Q需要?source 1.4 标记Q?
javac -source 1.4 Test.java
要在q行时启用断aQ可使用 -enableassertions 或?-ea 标记?
要在q行旉择用断言Q可使用 -da 或?-disableassertions 标记?
要系l类中启用断aQ可使用 -esa 或?-dsa 标记。还可以在包的基上启用或者禁用断a?
可以在预计正常情况下不会到达的Q何位|上攄断言。断a可以用于验证传递给U有Ҏ的参数。不q,断言不应该用于验证传递给公有Ҏ的参敎ͼ因ؓ不管是否启用了断aQ公有方法都必须查其参数。不q,既可以在公有Ҏ中,也可以在非公有方法中利用断言试后置条g。另外,断言不应该以M方式改变E序的状态?


W八QGC是什? Z么要有GC? (基础)?
GC是垃圾收集器。Java E序员不用担心内存管理,因ؓ垃圾攉器会自动q行理。要h垃圾攉Q可以调用下面的Ҏ之一Q?
System.gc()
Runtime.getRuntime().gc()

W九QString s = new String("xyz");创徏了几个String Object?
两个对象Q一个是“xyx?一个是指向“xyx”的引用对象s?

W十QMath.round(11.5){於多少? Math.round(-11.5){於多少?
Math.round(11.5)q回QlongQ?2QMath.round(-11.5)q回QlongQ?11;

W十一Qshort s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
short s1 = 1; s1 = s1 + 1;有错Qs1是short型,s1+1是int?不能昑ּ转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确?

W十二,sleep() ?wait() 有什么区? 搞线E的最?
sleep()Ҏ是ɾU程停止一D|间的Ҏ。在sleep 旉间隔期满后,U程不一定立x复执行。这是因为在那个时刻Q其它线E可能正在运行而且没有被调度ؓ攑ּ执行Q除?a)“醒来”的U程h更高的优先
(b)正在q行的线E因为其它原因而阻塞?
wait()是线E交互时Q如果线E对一个同步对象x 发出一个wait()调用Q该U程会暂停执行,被调对象q入{待状态,直到被唤醒或{待旉到?



W十三,Java有没有goto?
Goto?java中的保留字,现在没有在java中用?

W十四,数组有没有length()q个Ҏ? String有没有length()q个ҎQ?
数组没有length()q个ҎQ有length的属性?
String有有length()q个Ҏ?

W十五,Overload和Override的区别。Overloaded的方法是否可以改变返回值的cd?
Ҏ的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父cM子类之间多态性的一U表玎ͼ重蝲Overloading是一个类中多态性的一U表现。如果在子类中定义某Ҏ与其父类有相同的名称和参敎ͼ我们说该Ҏ被重?(Overriding)。子cȝ对象使用q个ҎӞ调用子cM的定义,对它而言Q父cM的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参C数或有不同的参数cdQ则UCؓҎ的重?Overloading)。Overloaded的方法是可以改变q回值的cd?

W十六,Set里的元素是不能重复的Q那么用什么方法来区分重复与否? 是用==q是equals()? 它们有何区别?
Set里的元素是不能重复的Q那么用iterator()Ҏ来区分重复与否。equals()是判M个Set是否相等?
equals()?=Ҏ军_引用值是否指向同一对象equals()在类中被覆盖Qؓ的是当两个分ȝ对象的内容和cd盔R的话Q返回真倹{?

W十七,l我一个你最常见到的runtime exception?
ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException,
ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFORMatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException

W十八,error和exception有什么区?
error 表示恢复不是不可能但很困隄情况下的一U严重问题。比如说内存溢出。不可能指望E序能处理这L情况?
exception 表示一U设计或实现问题。也是_它表C如果程序运行正常,从不会发生的情况?


W十九,List, Set, Map是否l承自Collection接口?
ListQSet?

Map不是

W二十,abstract class和interface有什么区?
声明Ҏ的存在而不d现它的类被叫做抽象类Qabstract classQ,它用于要创徏一个体现某些基本行为的c,qؓ该类声明ҎQ但不能在该cM实现该类的情c不能创建abstract cȝ实例。然而可以创Z个变量,其类型是一个抽象类Qƈ让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract cȝ子类为它们父cM的所有抽象方法提供实玎ͼ否则它们也是抽象cMؓ。取而代之,在子cM实现该方法。知道其行ؓ的其它类可以在类中实现这些方法?
接口QinterfaceQ是抽象cȝ变体。在接口中,所有方法都是抽象的。多l承性可通过实现q样的接口而获得。接口中的所有方法都是抽象的Q没有一个有E序体。接口只可以定义static final成员变量。接口的实现与子cȝ|除了该实现类不能从接口定义中l承行ؓ。当cd现特D接口时Q它定义Q即程序体l予Q所有这U接口的Ҏ。然后,它可以在实现了该接口的类的Q何对象上调用接口的方法。由于有抽象c,它允怋用接口名作ؓ引用变量的类型。通常的动态联~将生效。引用可以{换到接口cd或从接口cd转换Qinstanceof q算W可以用来决定某对象的类是否实现了接口?

W二十一Qabstract的method是否可同时是static,是否可同时是nativeQ是否可同时是synchronized?
都不?

W二十二Q接口是否可l承接口? 抽象cL否可实现(implements)接口? 抽象cL否可l承实体c?concrete class)?
接口可以l承接口。抽象类可以实现(implements)接口Q抽象类是否可承实体类Q但前提是实体类必须有明的构造函数?

W二十三Q启动一个线E是用run()q是start()?
启动一个线E是调用start()ҎQɾU程所代表的虚拟处理机处于可运行状态,q意味着它可以由JVM调度q执行。这q不意味着U程׃立即q行。run()Ҏ可以产生必须退出的标志来停止一个线E?



W二十四Q构造器Constructor是否可被override?
构造器Constructor不能被承,因此不能重写OverridingQ但可以被重载Overloading?

W二十五Q是否可以承Stringc?
StringcLfinalcL不可以ѝ?

W二十六Q当一个线E进入一个对象的一个synchronizedҎ后,其它U程是否可进入此对象的其它方?
不能Q一个对象的一个synchronizedҎ只能׃个线E访问?

W二十七Qtry {}里有一个return语句Q那么紧跟在q个try后的finally {}里的code会不会被执行Q什么时候被执行Q在return前还是后?
会执行,在return前执行?


W二十八Q编E题: 用最有效率的Ҏ出2乘以8{於?
有C背景的程序员特别喜欢问这U问题?

2 << 3

W二十九Q两个对象值相?x.equals(y) == true)Q但却可有不同的hash codeQ这句话对不?
不对Q有相同的hash code?

W三十,当一个对象被当作参数传递到一个方法后Q此Ҏ可改变这个对象的属性,q可q回变化后的l果Q那么这里到底是g递还是引用传?
是g递。Java ~程语言只由g递参数。当一个对象实例作Z个参数被传递到Ҏ中时Q参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变Q但对象的引用是永远不会改变的?


W三十一Qswtich是否能作用在byte上,是否能作用在long上,是否能作用在String?
switchQexpr1Q中Qexpr1是一个整数表辑ּ。因此传递给 switch ?case 语句的参数应该是 int?short?char 或?byte。long,string 都不能作用于swtich?

W三十二Q编E题: 写一个Singleton出来?
Singleton模式主要作用是保证在Java应用E序中,一个类Class只有一个实例存在?
一般Singleton模式通常有几U种形式:
W一UŞ? 定义一个类Q它的构造函Cؓprivate的,它有一个static的private的该cd量,在类初始化时实例话,通过一个public的getInstanceҎ获取对它的引?l而调用其中的Ҏ?
public class Singleton {
  private Singleton(){}
  //在自己内部定义自׃个实例,是不是很奇怪?
  //注意q是private 只供内部调用
  private static Singleton instance = new Singleton();
  //q里提供了一个供外部讉K本class的静态方法,可以直接讉K  
  public static Singleton getInstance() {
    return instance;   
   }
}
W二UŞ?
public class Singleton {
  private static Singleton instance = null;
  public static synchronized Singleton getInstance() {
  //q个Ҏ比上面有所改进Q不用每ơ都q行生成对象Q只是第一ơ     
  //使用时生成实例,提高了效率!
  if (instance==null)
    instanceQnew Singleton();
return instance;   }
}
其他形式:
定义一个类Q它的构造函Cؓprivate的,所有方法ؓstatic的?
一般认为第一UŞ式要更加安全?



Hashtable和HashMap
Hashtablel承自Dictionaryc,而HashMap是Java1.2引进的Map interface的一个实?

HashMap允许null作ؓ一个entry的key或者valueQ而Hashtable不允?

q有是QHashMap把Hashtable的containsҎL了,Ҏcontainsvalue和containsKey。因为containsҎҎ让h引v误解?

最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是Q在
多个U程讉KHashtableӞ不需要自׃ؓ它的Ҏ实现同步Q而HashMap
必Mؓ之提供外同步?

Hashtable和HashMap采用的hash/rehash法都大概一P所以性能不会有很大的差异?

Shooper.Java 2006-05-30 23:13 发表评论
]]>
字符Q字节和~码http://m.tkk7.com/shooper/articles/46507.htmlShooper.JavaShooper.JavaTue, 16 May 2006 15:46:00 GMThttp://m.tkk7.com/shooper/articles/46507.htmlhttp://m.tkk7.com/shooper/comments/46507.htmlhttp://m.tkk7.com/shooper/articles/46507.html#Feedback0http://m.tkk7.com/shooper/comments/commentRss/46507.htmlhttp://m.tkk7.com/shooper/services/trackbacks/46507.html 字符Q字节和~码

[原创文章Q{载请保留或注明出处:http://www.regexlab.com/zh/encoding.htm]

U别Q中U?/p>

摘要Q本文介l了字符与编码的发展q程Q相x늚正确理解。D例说明了一些实际应用中Q编码的实现Ҏ。然后,本文讲述了通常对字W与~码的几U误解,׃q些误解而导致ؕ码生的原因Q以及消除ؕ码的办法。本文的内容늛了“中文问题”,“ؕ码问题”?/p>

掌握~码问题的关键是正确地理解相x念,~码所涉及的技术其实是很简单的。因此,阅读本文旉要慢d惻I多思考?/p>

引言

“字W与~码”是一个被l常讨论的话题。即使这P时常出现的ؕ码仍然困扰着大家。虽然我们有很多的办法可以用来消除ؕ码,但我们ƈ不一定理解这些办法的内在原理。而有的ؕ码生的原因Q实际上׃底层代码本n有问题所D的。因此,不仅是初学者会对字W编码感到模p,有的底层开发h员同样对字符~码~Z准确的理解?/p>

回页?/a>

1. ~码问题的由来,相关概念的理?/h4>

1.1 字符与编码的发展

从计机对多国语a的支持角度看Q大致可以分Z个阶D:

  pȝ内码 说明
阶段一 ASCII 计算机刚开始只支持pQ其它语a不能够在计算Z存储和显C?/td> 英文 DOS
阶段?/td> ANSI~码
Q本地化Q?/td>
Z计算机支持更多语aQ通常使用 0x80~0xFF 范围?2 个字节来表示 1 个字W。比如:汉字 '? 在中文操作系l中Q?[0xD6,0xD0] q两个字节存储?br />
不同的国家和地区制定了不同的标准Q由此生了 GB2312, BIG5, JIS {各自的~码标准。这些?2 个字节来代表一个字W的各种汉字延׾~码方式Q称?b> ANSI ~码。在体中文系l下QANSI ~码代表 GB2312 ~码Q在日文操作pȝ下,ANSI ~码代表 JIS ~码?br />
不同 ANSI ~码之间互不兼容Q当信息在国际间交流Ӟ无法属于两U语a的文字,存储在同一D?b> ANSI ~码的文本中?/td>
中文 DOSQ中?Windows 95/98Q日?Windows 95/98
阶段?/td> UNICODE
Q国际化Q?/td>
Z使国际间信息交流更加方便Q国际组l制定了 UNICODE 字符?/b>Qؓ各种语言中的每一个字W设定了l一q且唯一的数字编P以满语言、跨q_q行文本转换、处理的要求?/td> Windows NT/2000/XPQLinuxQJava

字符串在内存中的存放ҎQ?/p>

?ASCII 阶段Q?b>单字节字W串使用一个字节存放一个字W(SBCSQ。比如,"Bob123" 在内存中为:

42 6F 62 31 32 33 00
B o b 1 2 3 \0

在?ANSI ~码支持多种语言阶段Q每个字W用一个字节或多个字节来表C(MBCSQ,因此Q这U方式存攄字符也被UC多字节字W?/b>。比如,"中文123" 在中?Windows 95 内存中ؓ7个字节,每个汉字?个字节,每个英文和数字字W占1个字节:

D6 D0 CE C4 31 32 33 00
?/td> ?/td> 1 2 3 \0

?UNICODE 被采用之后,计算机存攑֭W串Ӟ改ؓ存放每个字符?UNICODE 字符集中的序受目前计机一般?2 个字节(16 位)来存放一个序PDBCSQ,因此Q这U方式存攄字符也被UC宽字节字W?/b>。比如,字符?"中文123" ?Windows 2000 下,内存中实际存攄?5 个序P

2D 4E 87 65 31 00 32 00 33 00 00 00      ??x86 CPU 中,低字节在?/font>
?/td> ?/td> 1 2 3 \0  

一共占 10 个字节?/p>

回页?/a>

1.2 字符Q字节,字符?/h5>

理解~码的关键,是要把字W的概念和字节的概念理解准确。这两个概念ҎhQ我们在此做一下区分:

  概念描述 举例
字符 Z使用的记P抽象意义上的一个符受?/td> '1', '?, 'a', '$', 'K?, …?/td>
字节 计算Z存储数据的单元,一?位的二进制数Q是一个很具体的存储空间?/td> 0x01, 0x45, 0xFA, …?/td>
ANSI
字符?/td>
在内存中Q如果“字W”是?ANSI ~码形式存在的,一个字W可能用一个字节或多个字节来表C,那么我们U这U字W串?ANSI 字符?/b>或?b>多字节字W串?/td> "中文123"
Q占7字节Q?/font>
UNICODE
字符?/td>
在内存中Q如果“字W”是以在 UNICODE 中的序号存在的,那么我们U这U字W串?UNICODE 字符?/b>或?b>宽字节字W串?/td> L"中文123"
Q占10字节Q?/font>

׃不同 ANSI ~码所规定的标准是不相同的Q因此,对于一个给定的多字节字W串Q我们必ȝ道它采用的是哪一U编码规则,才能够知道它包含了哪些“字W”。而对?UNICODE 字符?/b>来说Q不在什么环境下Q它所代表的“字W”内ҎL不变的?/p>

回页?/a>

1.3 字符集与~码

各个国家和地区所制定的不?ANSI ~码标准中,都只规定了各自语a所需的“字W”。比如:汉字标准QGB2312Q中没有规定韩国语字W怎样存储。这?ANSI ~码标准所规定的内容包含两层含义:

  1. 使用哪些字符。也是说哪些汉字,字母和符号会被收入标准中。所包含“字W”的集合叫做?b>字符?/b>”?
  2. 规定每个“字W”分别用一个字节还是多个字节存储,用哪些字节来存储Q这个规定就叫做?b>~码”?

各个国家和地区在制定~码标准的时候,“字W的集合”和“编码”一般都是同时制定的。因此,q_我们所说的“字W集”,比如QGB2312, GBK, JIS {,除了有“字W的集合”这层含义外Q同时也包含了“编码”的含义?/p>

?b>UNICODE 字符?/b>”包含了各种语言中用到的所有“字W”。用来给 UNICODE 字符集编码的标准有很多种Q比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig {?/p>

回页?/a>

1.4 常用的编码简?/h5>

单介l一下常用的~码规则Qؓ后边的章节做一个准备。在q里Q我们根据编码规则的特点Q把所有的~码分成三类Q?/p>
分类 ~码标准 说明
单字节字W编?/td> ISO-8859-1 最单的~码规则Q每一个字节直接作Z?UNICODE 字符。比如,[0xD6, 0xD0] q两个字节,通过 iso-8859-1 转化为字W串Ӟ直接得?[0x00D6, 0x00D0] 两个 UNICODE 字符Q即 "?D"?br />
反之Q将 UNICODE 字符串通过 iso-8859-1 转化为字节串Ӟ只能正常转化 0~255 范围的字W?/td>
ANSI ~码 GB2312,
BIG5,
Shift_JIS,
ISO-8859-2 …?/td>
?UNICODE 字符串通过 ANSI ~码转化为“字节串”时Q根据各自编码的规定Q一?UNICODE 字符可能转化成一个字节或多个字节?br />
反之Q将字节串{化成字符串时Q也可能多个字节转化成一个字W。比如,[0xD6, 0xD0] q两个字节,通过 GB2312 转化为字W串Ӟ得?[0x4E2D] 一个字W,?'? 字?br />
“ANSI ~码”的特点Q?br />1. q些“ANSI ~码标准”都只能处理各自语言范围之内?UNICODE 字符?br />2. “UNICODE 字符”与“{换出来的字节”之间的关系是h定的?/td>
UNICODE ~码 UTF-8,
UTF-16, UnicodeBig …?/td>
与“ANSI ~码”类似的Q把字符串通过 UNICODE ~码转化成“字节串”时Q一?UNICODE 字符可能转化成一个字节或多个字节?br />
与“ANSI ~码”不同的是:
1. q些“UNICODE ~码”能够处理所有的 UNICODE 字符?br />2. “UNICODE 字符”与“{换出来的字节”之间是可以通过计算得到的?/td>

我们实际上没有必要去q每一U编码具体把某一个字W编码成了哪几个字节Q我们只需要知道“编码”的概念是把“字W”{化成“字节”就可以了。对于“UNICODE ~码”,׃它们是可以通过计算得到的,因此Q在Ҏ的场合,我们可以M解某一U“UNICODE ~码”是怎样的规则?/p>

回页?/a>

2. 字符与编码在E序中的实现

2.1 E序中的字符与字?/h5>

?C++ ?Java 中,用来代表“字W”和“字节”的数据cdQ以及进行编码的ҎQ?/p>
cd或操?/b> C++ Java
字符 wchar_t char
字节 char byte
ANSI 字符?/td> char[] byte[]
UNICODE 字符?/td> wchar_t[] String
字节东y字符?/td> mbstowcs(), MultiByteToWideChar() string = new String(bytes, "encoding")
字符东y字节?/td> wcstombs(), WideCharToMultiByte() bytes = string.getBytes("encoding")

以上需要注意几点:

  1. Java 中的 char 代表一个“UNICODE 字符Q宽字节字符Q”,?C++ 中的 char 代表一个字节?
  2. MultiByteToWideChar() ?WideCharToMultiByte() ?Windows API 函数?

回页?/a>

2.2 C++ 中相兛_现方?/h5>

声明一D字W串帔RQ?/p>
// ANSI 字符Ԍ内容长度 7 字节
char
     sz[20] = "中文123";

// UNICODE 字符Ԍ内容长度 5 ?wchar_tQ?0 字节Q?/span>
wchar_t wsz[20] = L"\x4E2D\x6587\x0031\x0032\x0033";

UNICODE 字符串的 I/O 操作Q字W与字节的{换操作:

// q行时设定当?ANSI ~码QVC 格式
setlocale(LC_ALL, ".936");

// GCC 中格?/span>
setlocale(LC_ALL, "zh_CN.GBK");

// Visual C++ 中用小?%sQ按?setlocale 指定~码输出到文?br />// GCC 中用大?%S
fwprintf(fp, L"%s\n", wsz);

// ?UNICODE 字符串按?setlocale 指定的编码{换成字节
wcstombs(sz, wsz, 20);
// 把字节串按照 setlocale 指定的编码{换成 UNICODE 字符?br />
mbstowcs(wsz, sz, 20);

?Visual C++ 中,UNICODE 字符串常量有更简单的表示Ҏ。如果源E序的编码与当前默认 ANSI ~码不符Q则需要?#pragma setlocaleQ告诉编译器源程序用的~码Q?/p>
// 如果源程序的~码与当前默?ANSI ~码不一_
// 则需要此行,~译时用来指明当前源E序使用的编?/font>

#pragma setlocale
(".936")

// UNICODE 字符串常量,内容长度 10 字节
wchar_t wsz[20] = L"中文123";

以上需要注?#pragma setlocale ?setlocale(LC_ALL, "") 的作用是不同的,#pragma setlocale 在编译时起作用,setlocale() 在运行时起作用?/p>

回页?/a>

2.3 Java 中相兛_现方?/h5>

字符串类 String 中的内容?UNICODE 字符Ԍ

// Java 代码Q直接写中文
String
string = "中文123";

// 得到长度?5Q因为是 5 个字W?/span>
System.out.println(string.length());

字符?I/O 操作Q字W与字节转换操作。在 Java ?java.io.* 中,以“Stream”结cM般是用来操作“字节串”的c,以“Reader”,“Writer”结cM般是用来操作“字W串”的cR?/p>
// 字符串与字节串间怺转化

// 按照 GB2312 得到字节Q得到多字节字符Ԍ

byte
[] bytes = string.getBytes("GB2312");

// 从字节按?GB2312 得到 UNICODE 字符?/span>
string = newString(bytes, "GB2312");

// 要将 String 按照某种~码写入文本文gQ有两种ҎQ?br />
// W一U办法:?Stream cd入已l按照指定编码{化好的字节串

OutputStream os = new FileOutputStream("1.txt");
os.write(bytes);
os.close();

// W二U办法:构造指定编码的 Writer 来写入字W串
Writer ow = new OutputStreamWriter(new FileOutputStream("2.txt"), "GB2312");
ow.write(string);
ow.close();

/* 最后得到的 1.txt ?2.txt 都是 7 个字?*/

如果 java 的源E序~码与当前默?ANSI ~码不符Q则在编译的时候,需要指明一下源E序的编码。比如:

E:\>javac -encoding BIG5 Hello.java

以上需要注意区分源E序的编码与 I/O 操作的编码,前者是在编译时起作用,后者是在运行时起作用?/p>

回页?/a>

3. 几种误解Q以及ؕ码生的原因和解军_?/h4>

3.1 Ҏ产生的误?/h5>
  对编码的误解
误解一 在将“字节串”{化成“UNICODE 字符东y时Q比如在d文本文gӞ或者通过|络传输文本ӞҎ“字节串”简单地作ؓ单字节字W串Q采用每“一个字节”就是“一个字W”的Ҏq行转化?br />
而实际上Q在非英文的环境中,应该“字节串”作?ANSI 字符Ԍ采用适当的编码来得到 UNICODE 字符Ԍ有可能“多个字节”才能得到“一个字W”?br />
通常Q一直在英文环境下做开发的E序员们Q容易有q种误解?/td>
误解?/td> ?DOSQWindows 98 {非 UNICODE 环境下,字符串都是以 ANSI ~码的字节Ş式存在的。这U以字节形式存在的字W串Q必ȝ道是哪种~码才能被正地使用。这使我们Ş成了一个惯性思维Q“字W串的编码”?br />
?UNICODE 被支持后QJava 中的 String 是以字符的“序号”来存储的,不是以“某U编码的字节”来存储的,因此已经不存在“字W串的编码”这个概念了。只有在“字W串”与“字节串”{化时Q或者,一个“字节串”当成一?ANSI 字符串时Q才有编码的概念?br />
不少的h都有q个误解?/td>

W一U误解,往往是导致ؕ码生的原因。第二种误解Q往往D本来ҎU正的ؕ码问题变得更复杂?/p>

在这里,我们可以看到Q其中所讲的“误解一”,即采用每“一个字节”就是“一个字W”的转化ҎQ实际上也就{同于采?iso-8859-1 q行转化。因此,我们常常使用 bytes = string.getBytes("iso-8859-1") 来进行逆向操作Q得到原始的“字节串”。然后再使用正确?ANSI ~码Q比?string = new String(bytes, "GB2312")Q来得到正确的“UNICODE 字符东y?/p>

回页?/a>

3.2 ?UNICODE E序在不同语a环境间移植时的ؕ?/h5>

?UNICODE E序中的字符Ԍ都是以某U?ANSI ~码形式存在的。如果程序运行时的语a环境与开发时的语a环境不同Q将会导?ANSI 字符串的昄p|?/p>

比如Q在日文环境下开发的?UNICODE 的日文程序界面,拿到中文环境下运行时Q界面上显CZؕ码。如果这个日文程序界面改为采?UNICODE 来记录字W串Q那么当在中文环境下q行Ӟ界面上将可以昄正常的日文?/p>

׃客观原因Q有时候我们必d中文操作pȝ下运行非 UNICODE 的日文YӞq时我们可以采用一些工P比如Q南极星QAppLocale {,暂时的模拟不同的语言环境?/p>

回页?/a>

3.3 |页提交字符?/h5>

当页面中的表单提交字W串Ӟ首先把字W串按照当前面的编码,转化成字节串。然后再每个字节{化成 "%XX" 的格式提交到 Web 服务器。比如,一个编码ؓ GB2312 的页面,提交 "? q个字符串时Q提交给服务器的内容?"%D6%D0"?/p>

在服务器端,Web 服务器把收到?"%D6%D0" 转化?[0xD6, 0xD0] 两个字节Q然后再Ҏ GB2312 ~码规则得到 "? 字?/p>

?Tomcat 服务器中Qrequest.getParameter() 得到qӞ常常是因为前面提到的“误解一”造成的。默认情况下Q当提交 "%D6%D0" l?Tomcat 服务器时Qrequest.getParameter() 返?[0x00D6, 0x00D0] 两个 UNICODE 字符Q而不是返回一?"? 字符。因此,我们需要?bytes = string.getBytes("iso-8859-1") 得到原始的字节串Q再?string = new String(bytes, "GB2312") 重新得到正确的字W串 "??/p>

回页?/a>

3.4 从数据库d字符?/h5>

通过数据库客LQ比?ODBC ?JDBCQ从数据库服务器中读取字W串Ӟ客户端需要从服务器获知所使用?ANSI ~码。当数据库服务器发送字节流l客LӞ客户端负责将字节按照正的~码转化?UNICODE 字符丌Ӏ?/p>

如果从数据库d字符串时得到qQ而数据库中存攄数据又是正确的,那么往往q是因ؓ前面提到的“误解一”造成的。解决的办法q是通过 string = new String( string.getBytes("iso-8859-1"), "GB2312") 的方法,重新得到原始的字节串Q再重新使用正确的编码{化成字符丌Ӏ?/p>

回页?/a>

3.5 电子邮g中的字符?/h5>

当一D?Text 或?HTML 通过电子邮g传送时Q发送的内容首先通过一U指定的字符~码转化成“字节串”,然后再把“字节串”通过一U指定的传输~码QContent-Transfer-EncodingQ进行{化得到另一东y字节串”。比如,打开一电子邮件源代码Q可以看到类似的内容Q?/p>
Content-Type: text/plain;
        charset="gb2312"
Content-Transfer-Encoding: base64

sbG+qcrQuqO17cf4yee74bGjz9W7+b3wudzA7dbQ0MQNCg0KvPKzxqO6uqO17cnnsaPW0NDEDQoNCg==

最常用?Content-Transfer-Encoding ?Base64 ?Quoted-Printable 两种。在对二q制文g或者中文文本进行{化时QBase64 得到的“字节串”比 Quoted-Printable 更短。在对英文文本进行{化时QQuoted-Printable 得到的“字节串”比 Base64 更短?/p>

邮g的标题,用了一U更短的格式来标注“字W编码”和“传输编码”。比如,标题内容?"?Q则在邮件源代码中表CZؓQ?/p>
// 正确的标题格?/span>
Subject: =?GB2312?B?1tA=?=

其中Q?/p>

  • W一个??”与?”中间的部分指定了字W编码,在这个例子中指定的是 GB2312?
  • ?”与?”中间的“B”代?Base64。如果是“Q”则代表 Quoted-Printable?
  • 最后?”与?=”之间的部分Q就是经q?GB2312 转化成字节串Q再l过 Base64 转化后的标题内容?

如果“传输编码”改?Quoted-PrintableQ同P如果标题内容?"?Q?/p>
// 正确的标题格?/span>
Subject: =?GB2312?Q?=D6=D0?=

如果阅读邮g时出Cؕ码,一般是因ؓ“字W编码”或“传输编码”指定有误,或者是没有指定。比如,有的发邮件组件在发送邮件时Q标?"?Q?/p>
// 错误的标题格?/span>
Subject: =?ISO-8859-1?Q?=D6=D0?=

q样的表C,实际上是明确指明了标题ؓ [0x00D6, 0x00D0]Q即 "?D"Q而不?"??/p>

回页?/a>

4. 几种错误理解的纠?/h4>

误解Q“ISO-8859-1 是国际编码??/h5>

非也。iso-8859-1 只是单字节字W集中最单的一U,也就是“字节编号”与“UNICODE 字符~号”一致的那种~码规则。当我们要把一个“字节串”{化成“字W串”,而又不知道它是哪一U?ANSI ~码Ӟ先暂时地把“每一个字节”作为“一个字W”进行{化,不会造成信息丢失。然后再使用 bytes = string.getBytes("iso-8859-1") 的方法可恢复到原始的字节丌Ӏ?/p>

误解Q“Java 中,怎样知道某个字符串的内码Q?/h5>

Java 中,字符串类 java.lang.String 处理的是 UNICODE 字符Ԍ不是 ANSI 字符丌Ӏ我们只需要把字符串作为“抽象的W号的串”来看待。因此不存在字符串的内码的问题?/p>

Shooper.Java 2006-05-16 23:46 发表评论
]]>lJAVA设计开发新手的一些徏议和意见http://m.tkk7.com/shooper/articles/45313.htmlShooper.JavaShooper.JavaTue, 09 May 2006 15:57:00 GMThttp://m.tkk7.com/shooper/articles/45313.htmlhttp://m.tkk7.com/shooper/comments/45313.htmlhttp://m.tkk7.com/shooper/articles/45313.html#Feedback0http://m.tkk7.com/shooper/comments/commentRss/45313.htmlhttp://m.tkk7.com/shooper/services/trackbacks/45313.html

作者:飞云侠    来自QCSDN

  Zl朋友同事一些设计问题上的指|Ҏ写此文,很多观点都是从别人的文章中获取,有些观点肯定也有偏颇Q有些观点也仅仅是提出ƈ没有做详l论qͼ请多拍砖Q以便改正?

  ?strong>概述?/p>

  在工作中Q作Z个程序员或者一个设计师QL要设计一些函数库或者一个框Ӟ当然最l常的还是做目Q即使是一个项目,也会被经常改动,甚至交给别h改动?br />  当你做这些工作的时候,你的q些成果都是要给别h了解使用的,或者说l以后的你用的Qؓ了别人的方便或者ؓ了自q方便Q我们要可能做好设计?br />  

  ?strong>放正心态,M东西都是不断发展?/strong>?/p>

  技术是日新月异的,每一天都有新的技术出来,正所?山外有山Qh外有?Q每一个新的轮子出来,都可能比你要设计的轮子好Q所以在设计的时候,应该了解一下是否已l有了类似的轮子Q是否要设计一个新的轮子?/p>

  即你的轮子已经设计好了Q也不好认ؓ自己的轮子一定比别h的轮子好Q虽然你的轮子可能更适合你的实际使用?/p>

  技术在不断的发展中Q你以及你的朋友/同事都在不断q步Q?士别三日Q当刮目相看"Q所以不要认Z的水q一定比别h高,"有所短,寸有所?Q所以别人对你的函数?框架提出意见Q提出疑问的时候,请不要惊奇,不要反感Q不要认为别人在"挑刺"Q也怽的函数库/框架早就不适合当前的发展了?br />  
  态度军_一切。你的领导或许更重视q一炏V?br />  
  ?strong>必要的组成部?单元试Q文档,实例Q手册etc?/p>

  单元试Q文档,API DocQ手册,演示E序QChange LogQReadmeQbuild。xml{等

  有一天别Z用了你设计的函数?框架Q当你升U后Q原来的目却不能工作了Q经q一天的调试Q你l于扑ֈ了原因,原来是不心写错了一个东ѝ?/p>

  你肯定不希望上述的事情发生,那么请你写单元测试吧Q这h不浪费自q旉Q也不耽误别h的工作,何乐而不为。你花在写单元测试的旉/带来的乐和你升U后Ҏ莫名其妙的错误的旉和苦恼相比,肯定更有价倹{你看到单元试的绿条,N不感到高兴吗?!

  如果你不能保证你的程序修Ҏ有错误,不要指望你的同事认ؓ你的错误是可以容忍的Q他们在心里早就开始骂你了Q呵c写单元试?br />  
  看看M一个知名的框架Q都包含完善的文档,单元试Q示例程序,用户手册Q那么请你也包含q些吧。哦Q对了,误l地写好JavaDocQ它很重要?br />  
  使用你的框架/函数库的人如果到处去找用方法,L某个c?但是他不知道是否有这个类)Q那么说明你的文档没有到位。如果你希望别h使用你的q个cL者功能,那么请写好文档,不要指望别h去读你的源码然后p理解它是q什么用的?br />  
  如果你做到这些,那么你的函数?框架也有?知名"的前提,N不是?如果没有Q我x没法让别人更好地使用的?br />  
  对了Q有了这些东西,q要有一个良好的目录l织Q这个也可以参考别的框架的l织方式?/p>

 ?strong>借鉴成熟的设计,参考已有的目?/p>

  1. 要做一个新的东西,没有x。不要惊Ӟ我肯定先找一个现有的东西来借鉴?br />  
  当然前提是不要重新发明轮子,或者是你有充分条g要重新发明一个轮子?br />  StrutsQWebWorkQ?a target="_blank">Spring{等都是成熟的框Ӟ不管你用v来是否符合你的习惯?br />  在你成ؓ大师之前Q你的设计思想估计前h都已l提出ƈ实践q了Q所以要勇敢地去借鉴?站在巨h的肩膀?我们能更q一步?br />  
  例如我们厌倦了在访问数据库时用如下的代码:

  try
  {
  //your code here
  }
  catch(Exception e)
  {
  //catch Exception
  }
  finally
  {
  //must do something
  }

  我们可以借鉴Spring框架的JdbcTemplatec,看看它是如何利用回调函数来处理的?
  
  我们使用hibernate时是不是也会使用cM上面的代码,那么可以参考Spring框架的HibernateTemplate?br />  
  借鉴也是一U捷径?br />  
  警告:借鉴但不要抄袭,借鉴代码要注明来源,重他h也是重自己?br />  
  2. 在实际的目中,往往可以参考已l有的项目来做自q设计?br />  
  例如做一个网站,我不知道如何讉K数据库,如何布局Q如何分层,那么我们可以参考已l有的网站程序,看看别h是如何利用SiteMesh或者tiles布局Q如何用Hibernate来访问数据库或者用已l封装好的JDBCcL讉K数据库,如何利用StrutsQWebWork或者其他访问来分层?/p>

  ?strong>遵守U定俗成的一些做?/strong>?

  Z使别人更方便C用你的东西,那么在设计一些通用的函数或者类的时候,请遵守通用的做法,不要与众不同Q除非你的内部实现确实与众不同?/p>

  例如实现一个类似ArrayList的类Q那么请不要q样?

  public int count()
  {
  return list.size();
  }
  public Item getItem(int i)
  {
  return list.get(i);
  }
  
  而应该这?

  public int size()
  {
  return list.size();
  }
  public Item get(int i)
  {
  return list.get(i);
  }
  
  当然每个人都有自qxQ如果你非常认ؓ你原来的方式比普通的好,那么h?套方式供别h选择。它不会l你带来ȝQ只是一个一看就懂的做法Q不用怀疑,q样做有好处?br />  
  很多cȝ设计都有一些约定俗成的做法Q那么在你设计一个新cȝ时候,先借鉴一下吧Q多看看JDK的源?文档Q看看别人是怎么实现的。这更有助于推广你的成果?br />    
  ?strong>不要q信权威?

  在用已有的框架或者函数库Ӟ不要认ؓ所有的东西都是正确的或者是最好的最好,肯定不是。没有完的东西Q已l存在的东西在设计的时候因为种U局限或者因Z者的水^Q对现在来说肯定存在不合理的设计Q或者过于理惛_的设计,而不能满_际情c?br />  
  不迷信权威,才能到达新的境界?/p>

  ?strong>不要L排斥Q不了解׃要草率发表意见,要严?/strong>?/p>

  在网上经常看到。Net和Java的比?火拼Q或者是Struts VS Webwork或者是其他{等Q非怹多。经常看到的是一方对Ҏ的东西不甚了解,开始批评,l果说不到点子上Q反而被嘲笑一番?br />  几种技术的比较有时候是必要的,例如技术选型的时候。但是如果一些对q些技术根本不了解的h来选型Q来评判Q你能对l果信服?
  存在是合理QQ何技术都有其存在的理由,虽然有些东西早就q时了,但是在当时它也是应运而生的?br />  几种技术,都是来解军_L问题Q但是问题也有很多方面,解决方式也有很多U,每个人的x也都不一P思\也不一P所以没有绝对符合要求的技术,但是应该有符合你的技术,不符合你的技术不{于也不满别h的要求。所以不要轻易排斥别的东ѝ?br />  
  在做技术比较的时候,如果你不了解Q那么请不要L发表意见Q至你可以亲自M解,d践之后在发表你的意见岂不是更好?br />  
  在发表意见的时候,也要严}Q不要轻易下l论Q要l过求证Q否则一旦错误只会让ҎW话Q让你的同事看不起你。例如你说Hibernate3不支持jdk1?Q那么最好去好好扑ֈ你的证据Q否则就会成为错误?Hibernate3支持jdk1?)
  
  作ؓ一个技术h员,严}应该是我们的习惯之一Q无论做开发还是做设计?/p>

  ?strong>处理好你的异?/strong>?/p>

  异常处理是Java~程中非帔R要的一个部分。徏议在使用异常之前阅读或者?br />  
  下面从书中摘出几条徏?
  * l对不要忽略异常
  * 千万不要隐藏异常
  * 仅在不正常的情况下用异?br />  * 对可恢复的情况用可查异常,对程序错误用运行时异常(RunTimeException)
  * l方法引发的异常做文?br />  * 在详l信息里面包括失败捕获信?br />  * 使用finally避免资源泄漏
  * ....
  
  在这里特别提出的是,在开发中要特别处理NULL的情况,否则l常引发NullPointException异常Q在Java里这是一个最令h头疼的异怺?br />  如果你的E序因ؓ一个NULL|而报了几十个NullPointException的话Q不但得让h烦死Q而且q非帔R以找到错误所在。所以在Java中一定要注意q个问题?br />  如果你的函数不允许Null|那么可以截获它,抛出一个异常,或者给客户更友好的提示Q难道不好吗?
  
  让我们来看一个例?

  public String getName(User aUser)
  {
  //如果aUser为NullQ会发生什么情?br />  return aUser.getName();
  }
  
  很明显,如果参数为NullQ就会抛出异常。应该改?
  public String getName(User aUser)
  {
  if(null=aUser)
  {
  return "";
  }
  else
  {
  return aUser.getName();
  }
  }
  
  或者你要求参数不能为空Q还可以抛出一个异常,强制使用者不能传入空倹{?br />  
  q有l常被忽略的是RunTimeException和普通异常的区别Q在Java中,q是一个特D的异常c,E序中如果遇到这个异常,用户可以不截获它Q而如果是其他的普通异常,׃许要截获它。我们的代码l常q么?
  try
  {
  //your code here
  }
  catch(Exception e)
  {
  //do warn
  }

  q样写的话,截获了所有异常,当然也包括了RunTimeException?在很多情况下Q这是不合适的处理方式Q我们只应截获必要的异常Q而应该忽略RuntimeException?br />  
  关于RunTimeExceptionQ在Spring中还有更好的利用方式Q徏议阅读Spring框架中在事务中对异常的处理代码,例如对Jdbc抛出的SqlException的{换?br />  
  关于异常处理Q我提出几点:
  * 捕获异常而且再次抛出时要包含原来的异怿?br />  * 不要忘了RunTimeExceptionQ除非必要,否则不要用catch(Exception e)的方式捕h有异常?br />  * 不要用异常做程控制Q异常的性能代h比较高昂?ҎQ可能有Z同意。此处不详细讨论)
  * 不要把异常处理都抛给别hQ本函数有能力处理的׃要抛出?br />  
  在此读者详l阅L者?br />  
  ?strong>q度依赖?/p>

  在定位错误的时候,l常遇到览了七 八个文gq是没有扑ֈ什么地Ҏ行了真正需要的函数Q这个时候就非常郁闷。A调用了BQB调用了CQC调用了D。。。。。。让人找不到?br />  
  面对q样的程序,存在的问题不仅仅是定位错误麻烦,而且如果需要维护这L函数?框架Q恐怕你的有非常高的lM能力才行Q否则打L也不ȝ护?br />  
  那么我们自己最好不要写q样的程序出来给人用?/p>

  ?strong>滥用接口?/p>

  现在行"面对接口~程"Q这本n本来是不错,但是滥用接口的现象却l常发生?br />  "面向接口"Q于是所有的c都有一个对应的接口Q接口的函数声明和类一模一P而且一个接口只有一个类来实现它。这L面向接口有什么意义哪? (Z用Spring的事务的情况除外)
  
  Ҏ"q比Ҏ?Law of Demter)"Q一个对象应当对其他对象有尽可能的了解。一个接口内应该只定义对Ҏ需要的ҎQ而不要把一些没用的Ҏ声明攑֜接口里面?br />  
  例如如下一个类:
  
  public class MyCounter
  {
  private int n1;
  private int n2;
  public MyCounter(int n1Qint n2)
  {
  this。n1=n1;
  this。n2=n2;
  }
  
  public void setN1(int n1)
  {
  return this.n1 = n1;
  }
  public void setN2(int n2)
  {
  return this.n2 = n2;
  }
  public int getN1()
  {
  return n1;
  }
  public int getN2()
  {
  return n2;
  }
  
  public int getResult()
  {
  return n1 + n2;
  }
  }

  我们可以看到Q这个类的主要目的是得到计算l果Q所以正的接口应该cM:
    
  public interface Counter
  {
  int getResult();
  }
  
  但是很多情况下,l常是这L接口:
    
  public interface Counter
  {
  int getResult();
  int getN1();
  int getN2();
  void setN1(int n1);
  void setN2(int n2);
  }
    
  我们想一惻Iq样做有2个后?
  1. 除了getResult之外Q其他的函数我们Ҏ用不刎ͼ所以是多余的?br />  2. 如果我们要自己实C个CounterQ如果接口中仅仅定义了getResultQ我们仅仅需要实现它可以了。我们自qcd能是多个数运,有乘除加减等{各U运,参数也有可能是一些数l。但是如果按照第二种Ҏ声明接口的话Q我们就必须实现后面的四个方法,如果q样的话Q实现这样东西不仅没用,而且费旉。我们恐怕要大声骂娘了吧?br />  
  所以,接口有好的作用,但是不要滥用?br />  ?如果你的接口永远只有一个类实现Q那么可能就没有必要用接口?br />  ?你的接口只需要声明别人用到的函数卛_?/p>

  【空接口的用?/strong>

  在接口用的时候,I接口有2U情?
  1. cMCloneableQSerializableQ他们往往是做一个标讎ͼ表示需要某个功能。当然你也可以这么用Q来表示你的cd有某个功能,实现了你的某个接口?br />  2. 你的接口l承了别的接?非空)Q你的接口本w没有声明函数。这U情况一般是你不希望用户使用父接口来作ؓ参数cdQ因Z们的用途可能不同,此时可以用I接口来实现?br />  
  W一U情冉|们不再多_搜烦一下关于CloneableQSerializable的文章就会了解很多?br />  我们来看下面的代?

  public interface Text
  {
  String getText();
  }
  
  public interface SqlText extends Text
  {
  }

  可以看到QText接口是用于返回一个字W串。而SqlText是一个空接口Q它l承了Text接口。也是说SqlText也是一UText。但是我们可以知道,M一个字W串不一定是Sql字符Ԍ所以此时声明了一个SqlText接口来用于表名当前的字符串是一个Sql字符丌Ӏ你的函数可以这样声?

  public void doQuery(SqlText aSqlText)

  而不是这?br />  
  public void doQuery(Text aText)

  避免用户产生歧义的想法,一眼看去,明白应该传入一个Sql字符丌Ӏ?br />  
  【承层ơ过多?/strong>
  一般来_l承的层ơ不要过多,否则使用者可能会讨厌Q找一个函C很麻烦。很多Java语言查工具都你的l承层次不要过3层?br />  
  【Has A QIs AQ不要滥用ѝ?/strong>

  "我是一个Mp3"Q?我有一个Mp3"Q其实很Ҏ分L。但是在实际应用中,往往存在?我有一个Mp3"的情况当?我是一个Mp3"Q或者是Zh方便而放松了对自q要求Q甚臌沾沾自喜Q感觉找C个捷径?scud以前也干q这U事??br />  
  以前我曾l这样干q?我的逻辑cȝ接承了我的数据库访问类Q这h可以直接在逻辑c里面访?
  
  public MyLogic extends MyDBA
  
  aLogic.getInt("click");
  aLogic.getString("name");
  
  看v来是非常方便Q但是你的逻辑cd牢牢l在了DBA上,是一U非怸好的做法。现在我q样声明:

  public MyLogic
  
  MyDBA adba;
  
  adba.getInt("click");
  adba.getString("name");

  其实代码改动不大Q但是你的逻辑cM在牢牢绑在DBAw上了,何乐而不为?br />  
  其实q种现象在开发h员中间可能经常见刎ͼ我们要尽量避免。下面再来看一个例?
  
  //一个保存分信息的c?br />  
  public class PageInfo
  {
  private int page;
  private int pageCount;
  private int recPerPage;
  private int recCount;
  
  //getQset method list...
  }

  一般的情况是,在Dao中进行分|询,计算总记录,总页数等{,所以需要把PageInfo传给Dao。而在逻辑cMQ把传回来的分页信息数据推到FormBean或者是Action中?br />  也许你会q么惻I如果我的Action或者FormBeanl承了PageInfoQ岂不是要省很多事?br />  
  千万别这么干。ƈ不是所有的动作都需要分信息,你的FormBean和PageInfo没有l承的关pR也是说FormBean Has A PageInfoQ但是不是Is A PageInfo?br />  
  【保持外?行ؓ一致?/strong>

  外观一致其实很Ҏ理解Q例如你用size()表示得到一个List的大,那么在所有的ListcM你都用size()得到它的大小Q这是外观一致?br />  外观一致让用户更方便用你的函数库Q不用记住几个不同的表示同一个功能的函数名字。或者几个名字相同功能却不同的函数。那很p糕了?br />  
  行ؓ一致相对外观一致就相对比较隑ց刎ͼ但是优秀的设计师肯定会让他的成果行ؓ一_而不是出人意料的行ؓQ也不是一套强行规定的行ؓ?br />  
  我们来看下面的代?
  
  import java.util.HashMap;
  import java.util.Map;

  class UserInfo
  {
  private String realname;
  
  public UserInfo(String sName)
  {
  this.realname = sName;
  }
  
  public void setName(String sName)
  {
  this.realname = sName;
  }
  public String getName()
  {
  return this.realname;
  }
  }
  
  public class MyTest
  {
  
  Map userInfoMap = new HashMap();
  
  public void setUserInfo(String sName,UserInfo aInfo)
  {
  userInfoMap.put(sName,aInfo);
  
  userInfoMap.put(aInfo.getName(),aInfo);
  }
  
  public UserInfo getUserInfo(String sName)
  {
  return (UserInfo)userInfoMap.get(sName);
  }
  
  public static void main(String args[])
  {
  MyTest aTest = new MyTest();
  
  UserInfo aUserInfo = new UserInfo("王小?);
  
  aTest.setUserInfo("儿童团团?,aUserInfo);
  aTest.setUserInfo("三班班长",aUserInfo);
  
  UserInfo 儿童团团?= aTest.getUserInfo("儿童团团?);
  
  if(null!=儿童团团?
  {
  System.out.println(儿童团团?getName());
  }
  else
  {
  System.out.println("儿童团团?Not Found");
  }
  
  UserInfo 王小?= aTest.getUserInfo("王小?);
  
  if(null!=王小?
  {
  System.out.println(王小?getName());
  }
  else
  {
  System.out.println("王小?Not Found");
  }
  
  }
  }
  可以看到Q上面的代码q行l果?王小?Q也是说儿童团团长是王二Q王二本n也是王小二,q一切正常?br />  
  现在我们把setUserInfo里面的第一句注释掉:
  
  public void setUserInfo(String sName,UserInfo aInfo)
  {
  //userInfoMap.put(sName,aInfo);
  
  userInfoMap.put(aInfo.getName(),aInfo);
  }

  再次q行上面的代码,我们发现儿童团团长不存在了,但是王小二还在。还可以看出Q如果找"三班班长"的话Q肯定也找不刎ͼ也就是说只有依据王小二的真名才能扑ֈ王小二,其他Ҏ׃行了?br />  
  从上面的setUserInfo和getUserInfo分析Q如果采用修改后的代码,我们的程序就出现了行C一_而这是o惑不解的Q我们set了半天,却找不到Q岂不是令h恼火!
  
  当然上面的代码比较简单,通过单的修改p做到行ؓ一_但在实际~程中,往往因ؓ复杂的行为操作,l常会造成行ؓ不一_从而给开发h员带来困惑?/p>

  【MVCQMVC2QWEB设计~程的分层?/strong>

  请阅L?http://forum.javaeye.com/viewtopic.php?t=11712&postdays=0&postorder=asc&start=0

  【可扩展不等于功能强大,不要夸大其辞?/strong>

  现在的系l,因ؓ接口或者其他方法的使用Q都h很大的扩展性。但是扩展性不{于功能强大?br />  存在一个接口,用户可以实现自己的接口,实非常方便。但是如果你的系l本w只实现了一个接口或者根本没有实玎ͼ那么对用h说就谈不上方ѝ?br />  
  例如WebWork的validatorsQ本w是一个接口,但是实际上本w实现的具体cd,而且功能很差Q这个时候如果你说WebWork的校验器很厉宻I那么可能不太恰当了。当然扩展Webwork的Validatorq是非常方便的?br />  
  当然Q可扩展性还是需要的Q但是不要吹嘘,在这个Qw的q代Q让我们多干点实事?:)

  ?0/80原则?/strong>
  
  在工作中Q我l常惛_20/80原则Q也是"巴雷多原?。例如我们可以看?

  旉Q我?0%的时间会产生成果?0%
  
  产品Q品的20%带来利润?0%
  
  阅读Q?0%的书幅包括了内容的80%
  
  工作Q?0%的工作给我们80%的满?br />  
  演讲Q?0%的演讲生媄响的80%
  
  领导Q?0%的h作出80%的决?/p>

  从上面可以看出,很多时候它都很有说服力?br />  在这里我x到几点,但是和上面的可能出发Ҏ所不同:
  
  1、程序的80%都是在处理特D情况,所以我们一定要对特D情况重视,不要因ؓ是特D情况,׃很重视?0%的客户对Ҏ情况都很重视?br />  文档对特D情况也要详l描qͼ因ؓ开发h?0%的时候在查找q些东西Q而对那些l常用到的用法却很少查阅文档?br />  
  2、优化问?80%的瓶颈都出在20%的代码上Q所以在优化代码的时候不需要优化所有代码,只需要优?0%的关键代码就够了。当然追求完的人我们就不多说了?
  记得有一条优化的原则?不要优化!不要优化"Q是非常有道理的?br />  
  3、如果你20%的事情做怺Q往往会导?0%的事情都怺Q或者是D别h认ؓ你把事情几乎都做怺?br />  如果你对一些事情发表了一些很不严谨的看法Q那么别Z认ؓ你在别的事情上也很不严}?br />  依此cLQ代码质量,文档完整性等{,都会让h产生cM的推理?br />  
  (当然一个代码写的很q人,往往文档也很乱?
  
  【强制绑定是不受Ƣ迎的?/strong>

  不要在程序中强制l定一些额外的功能?br />  
  有的框架往往功能很多Q是"大型计算?Q有很多功能Q但是在我需要打字的时候,l我打字的功能即可,不要强制我用网l功能,打印功能Q负载均衡功能等{?br />  
  一般来_如果一个东西有很多功能Q那么做好做成可配置Q可插拔的,q样用户使用你的东西Q没必要在不使用高功能的时候,费用户的内存,盘。开发h员还得多copy好多lib文gQ占用调试时_岂不是很ȝ?br />  
  不要C送一Q我不想要就别给我?:)

  【有时候也得考虑兼容性?/strong>

  一般来_一个公司的客户会有很多Q用Lq行环境是各U各L。jdk1.3Qjdk1.4甚至q有jdk1.2。这h们在~程的时候就必须做一些妥协,有些函数库就不能使用?br />  如果q些用户的jdk不能升(一般来说都需要购买新的品才能升U?Q或者我们必dq些情况妥协Q那么我们就要在开发中考虑q些问题?br />  
  例如以前Q在Servlet 2.2的时候,因ؓ没有setCharacterEncodingQ我们必L动对各种字符q行转换。当Servlet2.3的时候,可以使用q个函数了。但是ؓ了客戯虑Q我们只好没有升U还是用原来的Ҏ?当然后来大多数用户都使用了新的App ServerQ我们就可以使用filter来处理编码问题了)?br />  
  向下兼容性确实让人头|JDK1.5也发布好久了Q不q我们现在也不能使用Q只能自己没事测试测试?br />  
  在编E的时候,一定要讄好IDE的兼Ҏ设|,防止我们使用了不能用的Ҏ。JbuilderQEclipse都有cM的设|?br />  
  【成本与现实Q给用户以选择余地?/strong>

  全文索,luceneQlike是三U对大文本字D|索的Ҏ。那么你采用哪一U呢?
  
  也许你会毫不犹U的说"全文? (我看你像TRS公司的托 :P)?br />  
  正如"强制l定是不受欢q的"里面所说的一P我还是觉得应该给用户以选择的余地?br />  
  全文索是要花q或者需要配|,而且一般来说数据库专用的全文检索都是不通用的,lucene是需要开发h员开发的Q只有like最单了Q但是太单了Q而且性能也差?br />  
  q个时候,也许我们应该提供几U方式供用户选择了,用户如何选择那就看他们了。。?br />  
  【结束语?/strong>

  实际开发设计中肯定q存在很多其他的问题Q本文不可能一一。到此ؓ止?:)
  
  希望各位在开发设计中成ؓ高水q的设计师?:)



Shooper.Java 2006-05-09 23:57 发表评论
]]>
从Coding Fan到真正的技术专?/title><link>http://m.tkk7.com/shooper/articles/45303.html</link><dc:creator>Shooper.Java</dc:creator><author>Shooper.Java</author><pubDate>Tue, 09 May 2006 15:23:00 GMT</pubDate><guid>http://m.tkk7.com/shooper/articles/45303.html</guid><wfw:comment>http://m.tkk7.com/shooper/comments/45303.html</wfw:comment><comments>http://m.tkk7.com/shooper/articles/45303.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/shooper/comments/commentRss/45303.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/shooper/services/trackbacks/45303.html</trackback:ping><description><![CDATA[ <div id="w44yask" class="clear"> </div> <div id="aaoam8i" class="item-body"> <div id="8w4a4yk" class="item-content"> <p align="center"> <font color="#0000ff">作者:happy_forever     来自Q?/font> <a > <font color="#0000ff">http://www.javafan.net</font> </a> </p> <p> <font color="#0000ff"> </font> </p> <font color="#0000ff">以下文章都是l典Q看不看随你的便Q我只希望知识掌握在更多中国人的手里Q?/font> <p> </p> <p> <font color="#0000ff">中国有很多小朋友Q他?8,9岁或21,2岁,通过自学也写了不代码,他们有的代码写的很漂亮,一些技术细节相当出众,也很有钻研精,但是他们被一些错误的认识和观点左叻I~Z对系l,对程序的整体理解能力Q这些hQ一个网上的朋友说得很好Q他们实际上只是一些Coding fansQ压Ҏ有资格称为程序员Q但是据我所知,不少网l公司的CTO是q样的coding fans,拿着吓h的工资,做着吓h的项目,目的结局通常也很吓h?</font> </p> <p> <font color="#0000ff">E序员基本素质: </font> </p> <p> <font color="#0000ff">作一个真正合格的E序员,或者说是可以真正合格完成一些代码工作的E序员,应该h的素质?</font> </p> <p> <font color="#0000ff"><strong>1Q团队精和协作能力</strong><br />把它作ؓ基本素质Qƈ不是不重要,恰恰相反Q这是程序员应该具备的最基本的,也是最重要的安w立命之本。把高水q程序员说成独行侠的都是在呓语,M个h的力量都是有限的Q即便如linusq样的天才,也需要通过l成强大的团队来创造奇q,那些遍布全球的ؓlinux写核心的高手们,没有协作_是不可想象的。独行侠可以作一些赚qY件发点小财,但是一旦进入一些大pȝ的研发团队,q入商业化和产品化的开发Q务,~Zq种素质的h完全不合格了?</font> </p> <p> <font color="#0000ff"><strong>2Q文档习?<br /></strong>说高水^E序员从来不写文档的肯定是^臭未q的毛孩子,良好的文档是正规研发程中非帔R要的环节Q作Z码程序员Q?0Q的工作旉写技术文档是很正常的Q而作为高U程序员和系l分析员Q这个比例还要高很多。缺乏文档,一个Y件系l就~Z生命力,在未来的查错Q升U以及模块的复用时就都会遇到极大的麻烦?</font> </p> <p> <font color="#0000ff"><strong>3Q规范化Q标准化的代码编写习?/strong><br />作ؓ一些外国知名Y件公司的规矩Q代码的变量命名Q代码内注释格式Q甚臛_套中行羃q的长度和函数间的空行数字都有明规定,良好的编写习惯,不但有助于代码的UL和纠错,也有助于不同技术h员之间的协作?<br />有些coding fans叫嚣高水q程序员写的代码旁h从来看不懂,q种叫嚣只能证明他们自己压根不配自称E序员。代码具有良好的可读性,是程序员基本的素质需求?<br />再看看整个linux的搭建,没有规范化和标准化的代码习惯Q全球的研发协作是绝对不可想象的?</font> </p> <p> <font color="#0000ff"><strong>4Q需求理解能?/strong><br />E序员需要理解一个模块的需求,很多朋友写E序往往只关注一个功能需求,他们把性能指标全部归结到硬Ӟ操作pȝ和开发环境上Q而忽视了本n代码的性能考虑Q有人曾l放a说写一个广告交换程序很单,q种Z来不知道在百万甚臛_万数量的访问情况下的性能指标是如何实现的Q对于这LE序员,你给他深蓝那套系l,他也做不出太极链的ƈ访能力。性能需求指标中Q稳定性,q访支撑能力以及安全性都很重要,作ؓE序员需要评估该模块在系l运营中所处的环境Q将要受到的负荷压力以及各种潜在的危险和恶意d的可能性。就q一点,一个成熟的E序员至需??q的目研发和跟t经验才有可能有心得?</font> </p> <p> <font color="#0000ff"><strong>5Q复用性,模块化思维能力</strong><br />l常可以听到一些程序员有这L抱怨,写了几年E序Q变成了熟练工,每天都是重复写一些没有Q何新意的代码Q这其实是中国Y件h才最大浪费的地方Q一些重复性工作变成了熟练E序员的主要工作Q而这些,其实是完全可以避免的?<br />复用性设计,模块化思维是要程序员在完成Q何一个功能模块或函数的时候,要多想一些,不要局限在完成当前d的简单思\上,x看该模块是否可以qq个pȝ存在Q是否可以通过单的修改参数的方式在其他pȝ和应用环境下直接引用Q这样就能极大避免重复性的开发工作,如果一个Y件研发单位和工作l能够在每一ơ研发过E中都考虑到这些问题,那么E序员就不会在重复性的工作中耽误太多旉Q就会有更多旉和精力投入到创新的代码工作中厅R?<br />一些好的程序模块代码,即便?0q代写成的,拿到现在攑ֈ一些系l里面作为功能模块都能适合的很好,而现在我看到的是Q很多小公司软g一升或改q就动辄全部代码重写Q大部分重复性工作无谓的费了时间和_֊?</font> </p> <p> <font color="#0000ff"><strong>6Q测试习?</strong><br />作ؓ一些商业化正规化的开发而言Q专职的试工程师是不可的Q但是ƈ不是说有了专职的试工程师程序员可以不q行自测QY件研发作Z工E而言Q一个很重要的特点就是问题发现的早Q解决的代hp低,E序员在每段代码Q每个子模块完成后进行认真的试Q就可以量一些潜在的问题最早的发现和解冻Iq样Ҏ体系l徏讄效率和可靠性就有了最大的保证?<br />试工作实际上需要考虑两方面,一斚w是正常调用的试Q也是看程序是否能在正常调用下完成基本功能Q这是最基本的测试职责,可惜在很多公司这成了唯一的测试Q务,实际上还差的q那Q第二方面就是异常调用的试Q比如高压力负荷下的E_性测试,用户潜在的异常输入情况下的测试,整体pȝ局部故障情况下该模块受影响状况的测试,频发的异常请求阻塞资源时的模块稳定测试等{。当然ƈ不是E序员要对自q每段代码都需要进行这U完整测试,但是E序员必L醒认识自q代码d在整体项目中的地位和各种性能需求,有针Ҏ的q行相关试q尽早发现和解决问题Q当然这需要上面提到的需求理解能力?</font> </p> <p> <font color="#0000ff"><strong>7Q学习和ȝ的能?/strong><br />E序员是人才很容易被淘汰Q很Ҏ落伍的职业,因ؓ一U技术可能仅仅在三两q内h领先性,E序员如果想安n立命Q就必须不断跟进新的技术,学习新的技能?<br />善于学习Q对于Q何职业而言Q都是前q所必需的动力,对于E序员,q种要求更加高了。但是学习也要找对目标,一些小coding fans们,他们也|z乐道于他们的学习能力,一会学会了aspQ一会儿学会了phpQ一会儿学会了jspQ他们把q个作ؓ炫耀的资本,盲目的追逐一些肤的Q表面的东西和名词,做网l程序不懂通讯传输协议Q做应用E序不懂中断向量处理Q这L技术h员,不管掌握了多所谓的新语aQ永q不会有质的提高?<br />善于ȝQ也是学习能力的一U体玎ͼ每次完成一个研发Q务,完成一D代码,都应当有目的的跟t该E序的应用状况和用户反馈Q随时ȝQ找到自q不Q这样逐步提高Q一个程序员才可能成长v来?<br />一个不具备成长性的E序员,即便眼前看是个高手,也不要选用Q因Z落伍的时候马上就C?<br />具备以上全部素质的hQ应当说是够格的E序员了Q请注意以上的各U素质都不是由IQ军_的,也不是大学某些课本里可以学习到的Q需要的仅仅是程序员对自己工作的认识Q是一U意识上的问题?</font> </p> <p> <font color="#0000ff">那么作ؓ高E序员,以至于系l分析员Q也是对于一个程序项目的设计者而言Q除了应该具备上q全部素质之外,q需要具备以下素质: </font> </p> <p> <font color="#0000ff"><strong>W一Q需求分析能?/strong><br />对于E序员而言Q理解需求就可以完成合格的代码,但是对于研发目的组l和理者,他们不但要理解客户需求,更多时候还要自行制定一些需求,Z么这么说呢? <br />一般而言Q进行研发Q务,也许是客h出需求,也许是市场和营销部门提出的需求,q时候对于研发部门,他们看到的不是一个完整的需求,通常而言Q该需求仅仅是一些功能上的要求,或者更正规些,可能获得一个完整的用户视图Q但是这都不够,因ؓ客户׃非技术因素多一些,他们可能很难提出完整和清晎ͼ或者说专业性的性能需求,但是对于目l织者和规划者,他必能够清醒认识到q些需求的存在q在完成需求分析报告的时候适当的提出,同时要完整和清晰的体现在设计说明书里面,以便于程序员~码时不会失去这些准则?<br />E序设计者必L理解用户需求所处的环境Qƈ针对性做出需求的分析QD例而言Q同样一个Y仉过ASPU用方式发布和通过License方式发布Q性能需求可能就是有区别的,前者强调的是更好的支撑能力和稳定性,而后者则可能更强调在各种q_下的普适性和安装使用的简h?</font> </p> <p> <font color="#0000ff"><strong>W二Q项目设计方法和程处理能力</strong><br />E序设计者必能够掌握不于两到三种的项目设计方法(比如自顶至下的设计方法,比如快速原型法{等Q,q能够根据项目需求和资源搭配来选择合适的设计Ҏq行目的整体设计。设计方法上选择不当Q就会耽误研发周期Q浪费研发资源,甚至影响研发效果?<br />一个程序设计者还需要把很多功夫用在程囄设计和处理上Q他需要做数据图以确立数据词典;他需要加工逻辑图以Ş成整体的pȝ处理程。一个流E有问题的系l,q代码多漂亮,每个模块多精_也不会成Z个好的系l。当Ӟ做好程分析q择好项目设计方法,都需要在需求分析能力上h_的把握?</font> </p> <p> <font color="#0000ff"><strong>W三Q复用设计和模块化分解能?/strong><br />q个g又是老调重谈Q前面基本素质上不是已经说明了这个问题吗Q?<br />作ؓ一个从事模块Q务的E序员,他需要对他所面对的特定功能模块的复用性进行考虑Q而作Z个系l分析h员,他要面对的问题复杂的多,需要对整体pȝ按照一U模块化的分析能力分解ؓ很多可复用的功能模块和函敎ͼqҎ一模块形成一个独立的设计需求。D个例子,好比是汽车生产,最早每辆汽车都是独立安装的Q每个部仉是量w定做的Q但是后来不一样了Q机器化大生产了Q一个汽车厂开始通过水U来生汽RQ独立部件开始具有一定的复用性,在后来标准化成ؓ大趋势,不同型号Q品牌甚至不同厂商的汽R部g也可以进行方便的换装和升U,q时候,汽R生的效率达到最大化。Y件工E也是同L道理Q一个成熟的软g行业Q在一些相关项目和pȝ中,不同的部件是可以随意换装的,比如微Y的许多桌面YӞ在很多操作模块(如打开文gQ保存文件等{)都是复用的同一套功能模块,而这些接口又通过一些类库提供给了桌面应用程序开发者方便挂接,q就是复用化的模块设计明昄一个佐证?<br />一个大型的Q错l复杂的应用pȝ分解成一些相对独立的Q具有高度复用性的Qƈ能仅仅依靠几个参数完成数据联pȝ模块l合Q是作ؓ高E序员和pȝ分析员一Ҏ重要的工作,合适的目设计ҎQ清晰的程图,是实现这一目标的重要保证?</font> </p> <p> <font color="#0000ff"><strong>W四Q整体项目评估能?/strong><br />作ؓpȝ设计人员Q必能够从全局出发Q对目又整体的清醒认识Q比如公司的资源配置是否合理和到位,比如工程q度安排是否能最大化体现效率又不至于无法按期完成。评估项目整体和各个模块的工作量Q评估项目所需的资源,评估目可能遇到的困难,都需要大量的l验U篏Q换a之,q是一U不断ȝ的篏计才能达到的境界。在西方一些Y件系l设计的带头人都是很q长的,比如4Q?0岁,甚至更老,他们在编码方面已l远q不如年Mh那样zȝQ但是就目评估而言Q他们几十年的经验积累就是最重要和宝늚财富。中国缺q么一代程序员Q主要还不是~那U年U的E序员,而是那种q纪的程序员基本上都是研I单位作出来的,都不是从专业的品化软g研发作出来的Q他们没有能U篏那种产品化研发的l验Q这也是没有办法的事情?</font> </p> <p> <font color="#0000ff"><strong>W五Q团队组l管理能?/strong><br />完成一个项目工E,需要团队的齐心协力Q作为项目设计者或研发的主hQ就应当有能力最大化发挥团队的整体力量,技术管理由于其专业性质Q不大同于一般的Z理Q因里面设计了一些技术性的指标和因素?<br />首先是工作的量化Q没有量化就很难做到合适的l效考核Q而程序量化又不是单的代码行数可以计算的,因此要求技术管理h员需要能真正评估一个模块的复杂性和工作量?<br />其次是对团队协作模式的调_一般而言Q程序开发的协作通常分ؓ组q行Q小l有ȝ序员方式的,也有民主方式的,ҎE序员之间的能力水^差距Q以及根据项目研发的需求,选择合适的l队方式Qƈ能将责权和成员的工作d紧密l合Q这h能最大发挥组队的效率?<br />一个代码水q高的hQ未必能成ؓ一个合格的目研发ȝQ这斚w的能力欠~往往是容易被忽视的?</font> </p> <p> <font color="#0000ff">lg可以看到Q作Z个主研发的负责人,一个项目设计者,所需要具备的素质和能力ƈ不是E序代码~写的能力,当然一般情况下Q一个程序员通过不断的ȝ提高辑ֈ了这U素质的时候,他所h的代码编写能力也已经相当不简单了Q但是请注意q里面的因果关系Q一个高水^的项目设计者通常已经是代码编写相当优U的h了,但是q不是一个代码相当优U的程序员可以胜任项目设计的工作Q这里面存在的也不是智商和课本的问题Q还是在于一个程序员在积累经验,逐步提升的时候没有意识到应当思考哪斚w的东西,没有有意识的项目的l织和复用设计进行揣摩,没有l常性的文档习惯和ȝ习惯Q不改变q些Q我们的合格的项目设计者还是非常欠~?</font> </p> <p> <font color="#0000ff">另外Qؓ防止有无聊的人和我较真,补充一点,本文针对目标是作商业化的软g目和工E,那些U研机构的编E高手,比如法高手Q比如图象处理高手,他们的工作是研究N而非直接完成商业软gQ当然最l间接成为商业品,比如微Y研究院在作的研究NQ,因此他们的素质可能是另外的东西,q些人(专家Q,q不能说是程序员Q不能用E序员的标准去衡量?</font> </p> <p> <font color="#0000ff">最后补充一点东西,一个Y仉目研发的设计程是怎样的呢Q以通常标准的设计方法ؓ例,Q不q笔者喜Ƣ快速原型法Q?</font> </p> <p> <font color="#0000ff">W一个步骤是<strong>市场调研</strong>Q技术和市场要结合才能体现最大h倹{?</font> </p> <p> <font color="#0000ff">W二个步骤是<strong>需求分?/strong>Q这个阶D需要出三样东西Q用戯图,数据词典和用h作手册。用戯图是该Y件用P包括l端用户和管理用P所能看到的面样式Q这里面包含了很多操作方面的程和条件。数据词典是指明数据逻辑关系q加以整理的东东Q完成了数据词典Q数据库的设计就完成了一半多。用h作手册是指明了操作流E的说明书。请注意Q用h作流E和用户视图是由需求决定的Q因此应该在软g设计之前完成Q完成这些,׃ؓE序研发提供了约束和准Q很遗憾太多公司都不是这样做的,因果颠倒,序不分Q开发工作和实际需求往往因此产生隔阂p的现象?<br />需求分析,除了以上工作Q笔者以Z为项目设计者应当完整的做出目的性能需求说明书Q因为往往性能需求只有懂技术的人才可能理解Q这需要技术专家和需求方Q客h公司市场部门Q能够有真正的沟通和了解?</font> </p> <p> <font color="#0000ff">W三个步骤是<strong>概要设计</strong>Q将pȝ功能模块初步划分Qƈl出合理的研发流E和资源要求。作为快速原型设计方法,完成概要设计可以进入编码阶D了Q通常采用q种Ҏ是因为涉及的研发d属于新领域,技术主h员一上来无法l出明确的详l设计说明书Q但是ƈ不是说详l设计说明书不重要,事实上快速原型法在完成原型代码后Q根据评结果和l验教训的ȝQ还要重新进行详l设计的步骤?</font> </p> <p> <font color="#0000ff">W四个步骤是<strong>详细设计</strong>Q这是考验技术专家设计思维的重要关卡,详细设计说明书应当把具体的模块以最‘干净’的方式(黑箱l构Q提供给~码者,使得pȝ整体模块化达到最大;一份好的详l设计说明书Q可以ɾ~码的复杂性减低到最低,实际上,严格的讲详细设计说明书应当把每个函数的每个参数的定义都精_l的提供出来Q从需求分析到概要设计到完成详l设计说明书Q一个Y仉目就应当说完成了一半了。换a之,一个大型Y件系l在完成了一半的时候,其实q没有开始一行代码工作。那些把作Y件的E序员简单理解ؓ写代码的Q就从根子上犯了错误了?</font> </p> <p> <font color="#0000ff">W五个步骤是<strong>~码</strong>Q在规范化的研发程中,~码工作在整个项目流E里最多不会超q?/2Q通常?/3的时_所谓磨刀不误砍柴功,设计q程完成的好Q编码效率就会极大提高,~码时不同模块之间的q度协调和协作是最需要小心的Q也怸个小模块的问题就可能影响了整体进度,让很多程序员因此被迫停下工作{待Q这U问题在很多研发q程中都出现q。编码时的相互沟通和应急的解决手段都是相当重要的,对于E序员而言Qbug永远存在Q你必须永远面对q个问题Q大名鼎鼎的微YQ可曾有q箋三个月不发补丁的时候吗Q从来没有! </font> </p> <p> <font color="#0000ff">W六个步骤是<strong>试</strong>Q测试有很多U:按照试执行方,可以分ؓ内部试和外部测试;按照试范围Q可以分为模块测试和整体联调Q按照测试条Ӟ可以分ؓ正常操作情况试和异常情冉|试;按照试的输入范_可以分ؓ全覆盖测试和抽样试。以上都很好理解Q不再解释?<br />MQ测试同h目研发中一个相当重要的步骤Q对于一个大型YӞ3个月?q的外部试都是正常的,因ؓ永远都会又不可预料的问题存在?<br />完成试后,完成验收q完成最后的一些帮助文档,整体目才算告一D落Q当然日后少不了升Q修补等{工作,只要不是想通过一锤子买卖骗钱Q就要不停的跟踪软g的运营状况ƈ持箋修补升Q知道这个Y件被d淘汰为止?</font> </p> <p> <font color="#0000ff">写这些步骤算不上卖弄什么,因ؓ实话讲我手边是一本《Y件工E》,在大学里q是计算Z业的必修评Q但是我知道很多E序员似乎从来都只是热衷于什么?0天精通VC》之cȝQ他们有些和我一h击队nQ没有正规学q这个专业,q有一些则早就在؜够学分后把q些真正有用的东西还l了老师?</font> </p> <p> <font color="#0000ff">|上现在也很躁Q一些coding fans乱嚷Ph视听Q实际上真正的技术专家很在|上乱发帖子的,如笔者这样不知天高地厚的Q其实实在是不上什么高手,只不q看不惯q种Ҏ术,对程序员的误解和胡说Q只好挺w而出Q做拨ؕ反正之言Q也希望那些q沉q于一些错误h士的coding fans们能认真xQ走到正途上Q毕竟那些聪明的头脑q远q没有发挥应有的价倹{?/font> </p> <div id="aymgcks" class="clear"> </div> </div> </div> <img src ="http://m.tkk7.com/shooper/aggbug/45303.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/shooper/" target="_blank">Shooper.Java</a> 2006-05-09 23:23 <a href="http://m.tkk7.com/shooper/articles/45303.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://m.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://scycho.com" target="_blank">žƷƵ</a>| <a href="http://726kxw.com" target="_blank">ɫվWWWþþž</a>| <a href="http://wwwfac286.com" target="_blank">ëƬ߹ۿ</a>| <a href="http://boyonet.com" target="_blank">޸߹ۿ</a>| <a href="http://888-28.com" target="_blank">岻Ƶ</a>| <a href="http://dqcjlb.com" target="_blank">޳߲</a>| <a href="http://qinglou31.com" target="_blank">һĻ</a>| <a href="http://mangshigas.com" target="_blank">ԶƵ߹ۿѲ </a>| <a href="http://k96d.com" target="_blank">ѿJIZZƵ</a>| <a href="http://3333seav.com" target="_blank">ۺ</a>| <a href="http://468862.com" target="_blank">ۺϼƵ</a>| <a href="http://xjyzz.com" target="_blank">av߹ۿҰ</a>| <a href="http://86trader.com" target="_blank">Ʒһʽâ</a>| <a href="http://wwwkk2347.com" target="_blank">ŷձ߹ۿ </a>| <a href="http://saohu533.com" target="_blank">Ļ޳AƬ</a>| <a href="http://35469642.com" target="_blank">Ļպ</a>| <a href="http://wuaiav.com" target="_blank">һ߹ۿѸ߹ۿ</a>| <a href="http://baicaijia666.com" target="_blank">99þۺϾƷ</a>| <a href="http://6777s.com" target="_blank">޵һ</a>| <a href="http://011107.com" target="_blank">ŷAVӰ߹ۿ</a>| <a href="http://54vpn.com" target="_blank">xxxxƵ</a>| <a href="http://666za.com" target="_blank">þ91ۿ</a>| <a href="http://3333seav.com" target="_blank">ƷŮͬһѲ</a>| <a href="http://ybcin.com" target="_blank">þþƷһԡ</a>| <a href="http://html5text.com" target="_blank">ۺ</a>| <a href="http://vvbbn.com" target="_blank">¹ŮһëƬ</a>| <a href="http://10242016.com" target="_blank"></a>| <a href="http://class3g.com" target="_blank">Ƭѿ</a>| <a href="http://zjhmpaper.com" target="_blank">͵޾Ʒ͵һ</a>| <a href="http://yx6768.com" target="_blank">޾ƷĻ鶹</a>| <a href="http://www5xsq.com" target="_blank">ŷAVӰ߹ۿ</a>| <a href="http://rr433.com" target="_blank">Ȱ׽һ</a>| <a href="http://cjfuli.com" target="_blank">ھƷ뿨123</a>| <a href="http://ystchem.com" target="_blank">ӰԺMV߹ۿƵ</a>| <a href="http://qimiaodh.com" target="_blank">ɫһëƬ</a>| <a href="http://kencery.com" target="_blank">Ůʮ·Ůbbw</a>| <a href="http://www-33758.com" target="_blank">þ޾ƷĻ</a>| <a href="http://www789789.com" target="_blank">޾Ʒav߹ۿ</a>| <a href="http://helloyp.com" target="_blank">ѾƷԲĹۿ</a>| <a href="http://youweidianqi.com" target="_blank">ҹƵվ</a>| <a href="http://hljjlhl.com" target="_blank">3dƷžžһ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>