KNIHT
百度首页 | 百度空间
 
文章列表
 
2008年08月25日 星期一 19:52

GUID:是 Globally Unique Identifier (全球唯一标识符)的缩写。它在空间上和时间上都是唯一的,其中48位是计算机网卡的mac地址(没有网卡的会根据其他算法得到)还包括60bit的时间戳。也成为UUID。
IID:是一个128bit(16字节byte)的GUID结构。用来表示每个方法,这里的方法指的是引出的一个接口,可以是一个类指针,也可以是一个函数指针(这点我还不确认 哈哈)。

 
2008年05月20日 星期二 22:07

P 290 :类类型和容器类型可以被直接返回 例如
// ok: 返回类型是 char 的 list
list<char> foo_bar();
     但是 这种方式效率比较低 按值返回的讨论见7.4 节  
P 294:什么时候将一个参数指定为引用比较合适呢 像 swap()的情况 它必须将一个参数改变
成指针来允许改变实参的值时就比较合适 引用参数的第二种普遍用法是向主调函数返回额
外的结果 第三种用法是向函数传递大型类对象
P 295:有人可能希望用引用参数以避免拷贝用作实参的大型类对象 同时 又希望防止函数修
改实参的值 如果引用参数不希望在被调用的函数内部被修改 那么把参数声明为 const 型
的引用是个不错的办法 这种方式能够使编译器防止无意的改变
P 297 :引用必须被初始化为指向一个对象 一旦初始化了 它就不能再
指向其他对象 指针可以指向一系列不同的对象也可以什么都不指向
    因为指针可能指向一个对象或没有任何对象 所以函数在确定指针实际指向一个有效的
对象之前不能安全地解引用 dereference 一个指针 例如
class X;
void manip( X *px )
{
// 在解引用指针之前确信它非 0
if ( px != 0 )

// 解引用指针
}
     另一方面 对于引用参数 函数不需要保证它指向一个对象 引用必须指向一个对象
甚至在我们不希望这样时也是如此

 
2008年04月17日 星期四 20:30
P226:vector的容量并不是每增加一个元素就调整一次的,而是一次申请的容量会因为插入元素的不同而不同。一般标准类型和简单类会多一些(85-250) ,复杂类会少一点(有拷贝构造函数类为复杂类)向vector里添加元素会调用元素的拷贝构造函数(如果提供了的话),删除时调用析构函数。
P229:定义一个指定容量的容器后,容器会把所有位置初始化为该类型的默认值。
也可以指定初始值,example:vector <int> intvector(vectorsize,-1);则所有值都被初始化为-1。
P230:vector之间的比较,从第一个元素开始比较,比较第一个不相当的元素,大的大。如果元素都相等,哪个vector元素多那个大。容量相等,每个元素相等,两个vector相等。
P231:定义一个vector的迭代器 vector<classtype>::iterator iteratorname
例如:vector<int>::iterator test1 ,
vector<string>::iterator iter = vec.begin();
vector<string>::iterator iter_end = vec.end();
除了 iterator 类型 每个容器还定义了一个 const iterator 类型 后者对于遍历const容器
是必需的 const iterator 允许以只读方式访问容器的底层元素.
容器对象也可以用 由一对 iterator 标记的起始元素和未元素后一位置之间的拷贝 来初
始化 例如 假设我们有
#include <vector>
#include <string>
#include <iostream>

int main()
{
vector<string> svec;

string intext;
while ( cin >> intext )
    svec.push_back( intext );

// process svec ...
}
     我们可以定义一个新的 vector 来拷贝 svec 的全部或部分元素
int main()
{
vector<string> svec;
// ...
// 用 svec 的全部元素初始化 svec2
vector<string> svec2( svec.begin(), svec.end() );

// 用 svec 的前半部分初始化 svec3
vector<string>::iterator it =
svec.begin() + svec.size()/2;
vector<string> svec3( svec.begin(), it );
// 处理 vectors ...
}
一个vector也可以通过指向一个数组头和尾的两个指针来初始化,但是指向尾的指针必须指向最后一个元素后边的元素的地址,他被用作终止条件 它指向的对象 通常指向容器或者数组中最后一个元素后
面的位置上 不包含在要被拷贝或遍历的元素之中
在 map 也叫关联数组 associative array 中 我们提供一个 键/值 对 键用来索引
map 而值用作被存储和检索的数据
当我们写如下语句时
word_count[ string("Anna") ] = 1;
     将发生以下事情
    1 一个未命名的临时 string对象被构造并传递给与map类相关联的下标操作符 这个
对象用 Anna 初始化
    2 在 word_count中查找 Anna 项 没有找到
    3 一个新的键/值对被插入到 word_count中 当然 键是一个 string对象 持有 Anna
但是 值不是 1 而是 0
    4 插入完成 接着值被赋为 1  
 
2008年04月15日 星期二 23:04

对于嵌入式系统来说,一般都需要一个bootloader来下载和引导操作系统,常用的bootloader有eboot,uboot以及vivi等,对于windows ce来说最理想的bootloader当然是eboot(我也做了利用uboot下载和引导ce,以后我会介绍)。下面我就把自己开发eboot的过程和大家分享。eboot的流程可以如下图所示:

1)eboot和nk公用一段起始代码fw.s,所以我们会在eboot文件夹下的arm子文件夹找到fw.s,里面就一句话: INCLUDE ..\\..\\kernel\\hal\\arm\\fw.s,对于这段起始代码我就不详细分析,无非是建立好中断向量表,设置好系统的工作频率,设置MMU等,然后就跳转到eboot的main函数

2)eboot的main函数在eboot文件夹的main.c里面,代码如下:

void main (void)

{

BootloaderMain ();

SPIN_FOREVER;

}

是不是觉得很简单,好像什么也没有做,但是注意这个BootloaderMain函数,这个就是eboot真正的main函数,这个函数在

$(_WINCEROOT)\PUBLIC\COMMON\OAK\DRIVERS\ETHDBG\BLCOMMON\blcommon.c里面,这个函数是微软的ce对eboot的通用函数,它会调用在eboot文件夹里面由OEM商或者自己写的一些函数。那既然我们知道了真正的main函数在哪里,那么下面我们跟着BootloaderMain走吧。

3)在BootloaderMain 函数里面首先执行KernelRelocate,这是把一些全局变量存放到ram里面去,这个函数不是很重要。

4)下面就是执行OEMDebugInit,看到OEM三个字母了没有,这就说明这个函数是OEM商,或者我们自己需要实现的,在eboot下的main函数里面可以找到这个函数,这主要是提供给blcommon一些回调函数如下所示:

BOOL OEMDebugInit()

{

// Assign callback functions to be usec by blcommon.

g_pOEMReportError = OEMReportError;//错误报告函数

g_pOEMVerifyMemory = OEMVerifyMemory;// 下载映象时检测内存是否正常

g_pOEMMultiBINNotify = OEMMultiBINNotify; //通知需要下载的所有bin文件

OEMInitDebugSerial();//初始化串口调试输出

return TRUE;

}

这些被调用的函数也是OEM商或者我们自己编写的。前面三个函数都可以在main.c里面找到,代码比较罗唆,而且基本上和硬件没有太大关系,我们看看最后一个初始化串口调试输出的函数,这个文件在D:\WINCE420\PLATFORM\smdk2410eboot+rtc\KERNEL\HAL\debug.c里面,我这里是设置串口0为调试输出口,三星自带的用的是串口1,并且把波特率设置为115200,大家如果需要用串口0作为调试输出口可以参考我的修改:

#define UART0BaudRate 115200

void OEMInitDebugSerial(void)

{

volatile UART1reg *s2410UART0 = (UART0reg *)UART0_BASE;

volatile IOPreg *s2410IOP = (IOPreg *)IOP_BASE;

s2410IOP->rGPHCON &= ~((3 << | (3 << 10));

s2410IOP->rGPHCON |= ((2 << 4) | (2 << 6)); //

s2410IOP->rGPHUP |= (1 << 2) | (1 << 3);

s2410UART0->rUFCON = 0x0; // Disable the FIFO

s2410UART0->rUMCON = 0x0; // Disable AFC.

s2410UART0->rULCON = 0x3; // Normal mode, N81.

s2410UART0->rUCON = 0x245;

s2410UART0->rUBRDIV = ( (int)(S2410PCLK/16.0/UART0BaudRate + 0.5) -1 );

}

调用完这个调试输出初始化函数以后,eboot的调试信息就会从串口0出来(当然nk的调试信息也会从这个串口出来了,因为这一部分是和nk复用的^_^)

5)BootloaderMain调用完OEMDebugInit后就调用下一个函数了-OEMPlatformInit,这个函数也在eboot的main.c里面可以找到,主要是初始化你的硬件平台,包括设置RTC时钟,初始化一下你的NANDflash,然后就是读TOC (table of contents),一般TOC都会烧到nand的block1里面,如果读TOC失败,就会用默认的参数重写TOC,读TOC这段代码比较简单,在fmd.cpp里面,大家可以自己研究。然后就是进入倒计时,如果在你设置的延迟时间内按键盘的话就会进入BootMonitor这个函数,这个函数主要是输出eboot的选择菜单,根据你的选择进行操作,如果在延迟时间结束你没有按键盘的话就会根据你设置的是Download new(下载新的映象)还是Launch existing(加载在nand中的映象)来进行下一步操作,我们先看看BootMonitor这个函数,这个函数虽然代码很多,但是其实非常简单,就是根据你的输入来设置改变一些全局变量,eboot在后面会根据这些变量来进行相应的操作。

如果选择了下载映象,在OEMPlatformInit函数里会调用InitEthDevice初始化网卡,然后返回true,InitEthDevice函数在ether.c里面,具体需要根据你使用的网卡,把一些接口提供给eboot,下面是我的InitEthDevice函数,我使用的是DM9000网卡:

BOOL InitEthDevice(PBOOT_CFG pBootCfg)

{

USHORT wMAC[3];

PBYTE pBaseIOAddress = NULL;

DWORD dwMultiplier = 0;

// Boot CS8900.

//

if (!pBaseIOAddress)

{

// Use the MAC address programmed into flash by the user.

//

memcpy(wMAC, pBootCfg->EdbgAddr.wMAC, 6);

pfnEDbgInit = DM9000DBG_Init;

pfnEDbgGetFrame = DM9000DBG_GetFrame;

pfnEDbgSendFrame = DM9000DBG_SendFrame;

pBaseIOAddress = (PBYTE)CS8900DBG_IOBASE;

dwMultiplier = CS8900DBG_MEMBASE;

memcpy(pDriverGlobals->eth.TargetAddr.wMAC, pBootCfg->EdbgAddr.wMAC, 6);

pDriverGlobals->misc.EbootDevice = (UCHAR)DOWNLOAD_DEVICE_CS8900;

}

// Initialize the built-in Ethenet controller.

//

if (!pfnEDbgInit((PBYTE)pBaseIOAddress, dwMultiplier, wMAC))

{

EdbgOutputDebugString("ERROR: InitEthDevice: Failed to initialize Ethernet controller.\r\n");

return(FALSE);

}

// Make sure MAC address has been programmed.

//

if (!wMAC[0] && !wMAC[1] && !wMAC[2])

{

EdbgOutputDebugString("ERROR: InitEthDevice: Invalid MAC address read from NIC.\r\n");

return(FALSE); }

memcpy(&pDriverGlobals->eth.TargetAddr.wMAC, &wMAC, (3 * sizeof(USHORT)));

return(TRUE);

}

DM9000DBG_Init; DM9000DBG_GetFrame; DM9000DBG_SendFrame;这几个函数都需要在你的网卡驱动里面实现,这里只需要把这几个函数提供给eboot就行了。

6)BootloaderMain下面就调用OEMPreDownload进行一些下载前的准备工作,之后就会调用DownloadImage下载内核,下载完了后就调用OEMLaunch启动RAM里面的内核,注意OEMLaunch里面会需要和PB建立连接,如果我们要绕过PB下载nk(我在以前的文章里面已经介绍过实现的方法了)我们就需要屏蔽这段代码(在#ifndef SIMULATOR #endif之间)。

7)如果我们选择了Launch existing image,在eboot的OEMPlatformInit里就会利用ReadRamImageFromBootMedia或者ReadKernelRegionFromBootMedia函数把nk从nand中读到ram里面,然后再启动内核。第一个函数是直接把内核从nand中拷贝到RAM里面,第二个函数必须要选择了支持binfs文件格式,它会把nand进行格式化成binfs,这些对nand操作的函数都再fmd.cpp里面,具体实现可以参考里面的代码。

8)以上介绍的都是eboot中比较重要的部分,其实在eboot的选择菜单里你还可以选择格式化nand,设置ip,mac地址等,总的来说,eboot的功能还是很强大的,但是和uboot比起来还是差了很多,因为它在人机交互上面做的不好,不如uboot那样强大。^_^!

 
2008年03月31日 星期一 12:41

鸡A 不会叫但很会下蛋
鸡B 很会叫但不会下蛋
鸡C 很会叫也很会下蛋
鸡D 不会叫也不会下蛋

现阶段,大量存在的是鸡A、B、D。
D是笨蛋,什么也干不了,但凭一个资格混,姑且不说它了
鸡A是最郁闷的,往往出了成果却被B占去了
它们什么都说不出,心里窝火,只能怨天尤人、精神抑郁
鸡C最聪明,它们知道宣传,自己作了工作,就要有相应的影响

什么时候鸡A们全都变成了鸡C,那么鸡B就没有了生存的空间
鸡D慢慢就不能称之为鸡了,被清理出鸡的队伍
那个时候我们的科研环境才算是开始净化了

学学国外的那些很牛的鸡,
蛋下得大,下得多,叫的更响!
这才算一个真正的鸡!

 
2008年03月20日 星期四 18:54

type * const pname    :不能改变指针指向的地址,可以改变指针指向对象的值
type const * pname    :可以改变指针指向的地址,不可以改变指针指向对象的值

 
2008年03月20日 星期四 15:15

http://www.ebigear.com
背诵是最古老,也是最有效的学习方法。

背诵可以帮助你练习发音,增加词汇,提高口语表达的流利程度!

背诵可以帮助你培养语感,强化写作,全面拓展自己的知识范围!

俗话说“熟读唐诗三百首,不会作诗也会吟。”

英语作为一种交际性较强的语言学习科目,如果能达到:“不会作诗也会吟”的境界,那何愁英语学不好呢?既然“会吟”,那么,困扰中国教育学家多年的哑巴英语不就迎刃而解了吗;把“会吟”的内容记录下来,这在无形中就解决了有些学习者为之头痛的写作教学;真可谓“一举三得”。

背诵可以帮助学习者加深对课文的理解,提高阅读能力,锻炼记忆力;还可以帮助学生学习课文中用词造句、布局谋篇的方法,培养和提高作文能力。有则外国谚语则说:“能背诵多少书籍,就能获得多少知识。”可见,背诵是英语学习能力提升中一个重要的方面。

对于大多数英语学习者而言,特别是大学生和已经在备考GRE及托福的朋友们,十多年的英语功底无论学的好与坏,在大量的英语阅读和接触中,他们的脑海中已经蕴藏了大量典范的英语句子,只不过由于日常生活中实在是太少的运用这一部分,已使这一部分记忆变成惰性了。正如GRE单词,很多学习者到最后也只能达到见词生义而不能把词运用在生活中一样,为什么呢?因为这些学习者实在很难再碰到这些词汇。思维需要不断的激活,才能让这部分记忆经常的活动于大脑皮层。背诵其实就是每天不断的刺激这部分惰性思维,久而久之,当我们再写作文时,大脑皮层活跃的是你十多年积累而一直没有被应用的英语句子。所以背诵是一剂良好的催化剂,值得广大英语学习者尝试一下。

现在有很多英语学习者都通过背诵《新概念英语》课文来提高自己的英语水平:很多重点中学的教师都要求其学生能够熟练背诵或默写《新概念英语》的第二册或第三册。部分准备考研及托福考试的考生也都通过背诵《新概念英语》来提高其英语口语和写作水平。实践证明,《新概念英语》教材中短小精悍、生动有趣的课文最适合用来背诵。

那么如何有效地进行英语背诵呢?

每个人都会根据自己的学习特点采取不同的学习方式,下面给大家推荐几种不同的背诵方法。

一、明确目的,集中精力

背诵一篇课文或者一段必须掌握的语句,最忌东张西望,漫不经心,注意力分散。如果是一篇很简单的文字,背了几天后仍老出错,这肯定是用心不专的缘故。至于出现“前记后忘”的现象,则是正常的,这时千万不要向这种暂时困难屈服而打退堂鼓。

二、反复阅读与再现相结合

背诵一篇短文,仅仅读几遍是行不通的,一定要熟读到滚瓜烂熟的程度才行。单纯地反复阅读效果并不好,学习者应该在文章还没有完全记住前积极进行尝试再现,回忆不起来时再阅读。这样容易记住,保持时间也长。特别生疏的语句,注意多尝试再现几次。因为尝试再现是一种比阅读更积极的智力活动,又是一种自我检查的过程,使人更能集中精力,掌握识记内容的重点、难点,并及时改正记忆中的错误。开始时可短一些,容易一些,然后作一定幅度的调整。

背诵过程中,如果“卡壳”,应该进行追忆。追忆是有意和间接再现的形式,它需要付出很大的意志力,克服一定的困难,多方面寻找线索,进行积极灵活的思维。因此,不能一“卡壳”就立即停止背诵。

文章通过理解消化,已纳入自己的知识系统,语句通过熟读试背,也已朗朗上口,如果再反复朗读几遍,就能流利地背诵下来。

复习背诵的时间用得越多,记住的效果就越佳。早晨背诵过的课文或知识,晚上睡前以及第二天起床后,应进行一次复背,并在每周六或周日再作适当的温习背诵,以后过一个月再复背一次。这样,可保证很长一段时期不会遗忘。这里需要提醒大家注意的是复习的时候可以把原文提炼成一个提纲,边看提纲,边复习背诵,这样记忆和熟练程度就会更加明显。下面是列提纲的一种形式,供大家参考。

原文:

One man in a boat(独坐孤舟)

Fishing is my favourite sport. I often fish for hours without catching anything. But this does not always worry me. Some fishermen are unlucky. Instead of catching fish, they catch old boots and rubbish. I am even less lucky. I never catch anything-not even old boots. After having spent whole morning on the river, I always go home with an empty bag. "You must give up fishing!" my friends say. "It's a waste of time." But they don't realize one important thing. I'm not really interested in fishing. I am only interested in sitting in a boat and doing nothing at all.(选自《新概念英语》第二册Lesson 20)

提纲:1. Fishing - favourite sport;2. often - hours - anything;3. some - unlucky;4. Instead - fish - boots - rubbish;5. I - less;6. never - even - boots;7. whole mornings - river - home - empty;8. give up - friends - waste;9. don't realize - important thing;10. not - interested - fishing;11. only - sitting - nothing

三、加强默写,强化训练

所谓“眼过千遍,不如手抄一遍”。这也是运用内部语言背诵的一种形式,既用脑,又动手,可加深对文章的记忆。因为文字本身就是一种图形和符号,经常默写可帮助我们促进右脑的开发。采取默写手段,可有效地巩固已经背诵了的课文和知识,而且对加深记忆大有好处。一篇文章,就这样一段一段地把它“吃掉”。最后,遵循“整体→部分→整体”的原则,按照背诵各段的方法,再把全篇串联起来,进行背诵。如果能切实做到循序渐进,长期进行默写训练,那么一定会有助于背诵的质量和效果。

另外,为了使所背诵的内容长久地保持在头脑中经久不忘,以便在实践中及时提取应用,学习者还应注意安排过度学习。实验表明,过度学习的效果优于适度学习的效果。所谓适度学习是指在识记材料刚刚达到背诵程度就中止的学习。而过度学习是指对识记材料达到背诵之后还继续进行学习

(作者:宋德伟 北京外国语大学外语教学与研究出版社 英语编辑)

 
2008年03月07日 星期五 06:50

带单一参数的构造函数在缺省情况下隐含一个转换操作符,请看下面的代码:

class C {
int i;
//...
public:
       C(int i);//constructor and implicit conversion operator
//as well
};

void f() {

C c(0);

c = 5; //将 5 隐式转换为 C 对象,然后赋值

}

编译器重新编辑上述例子代码,如下:

//////////////////////////////////////////////////////////////////////////////////////////
//"c=5;" 被编译器转换成下面这个样子:
/////////////////////////////////////////////////////////////////////////////////////////

C temp(5);// 实例化一个临时对象,
c = temp; // 用 = 赋值
temp.C::~C(); // temp 的析构函数被激活

在很多情况下,这个转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换,例如:

class String {
int size;
char *p;
//..
public:
        String (int sz); //这里不希望进行隐式转换操作
};
void f ()
{
     String s(10);

     // 下面是一个程序员的编码;发生一个意想不到的转换:

     s = 100; // 糟糕,100 被转换为一个 String,然后被赋值给 s
}

为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:

class String {
int size;
char *p;
//..
public:
        // 不要隐式转换
        explicit String (int sz);
        String (const char *s, int size n = 0); // 隐式转换
};

void f ()
{
     String s(10);

     s = 100; // 现在编译时出错;需要显式转换:

     s = String(100); // 好;显式转换
     s = "st";         // 好;此时允许隐式转换
}

 
2008年03月04日 星期二 06:53

什么是 Design Pattern?许多人一讲到 Design Pattern,就会扯到什么建筑设计,因为他们全都是看四人帮的「Design Patterns」经典本的解释,没消化就照单全收。 如果不能用更生活化的方式解释 Design Pattern,我会怀疑他们是不是真的了解 Design Pattern 的真义。

什么是 Pattern
Pattern 最简单的定义是:只要是一再重复出现的事物,就是 Pattern。依照此定义,生活中就可以找到一堆 Pattern 的例子:
第四台广告中的 Pattern:
原价 ...,现在购买只要 ...,还送你一组 ...,请马上来电 ...,如忙线中请稍后再拨。
利用分割画面显示出使用前使用后的差别,来加强说服力。例如:由 C 升级到 E(注:C 和 E 不是指程序语言)。
找人现身说法:「杰瑞!感谢你介绍这套欧莱礼 Java 系列,让我在短短的三个月内成为公司内首屈一指的 Java 专家,这实在是太神奇了!」

选举时的 Pattern:
1. 质疑对手 A 钱或搞婚外情
2. 把家人通通拉上台痛哭一场以示选情告急
3. 开口唱「爱拼才会赢」
其它像是金光党的手法,刮刮乐诈财的技俩 ... 等,也都具有一再重复出现的特性,所以都可算是 Pattern。

电影中的 Pattern
提高追杀时紧张程度的 Pattern
坏人追杀好人时,好人躲进车子,却发现车子发不动,引擎嘎嘎作响,一面努力地继续发动,一面念念有词「Come on, Come one」。
坏人追杀好人时,好人冲进电梯,死命地押着 close 按钮,脱口而出「Come on, Come one」。
许多电影都会使用上述两个 Pattern,虽然是老掉牙的 Pattern,但每次看到这里,总是让我紧张得心脏病差点发作,我不得不承认这两个 Pattern 实在是挺有效的。

增加主角杀死坏人合理性的 Pattern
电影最后,坏人和好人大对决,最后好人胜利,但是好人如果直接把坏人宰了,那好人在观众心中的形象就会受损,所以好人先饶坏人一条生路,但是坏人却坏到骨子里了, 偷偷拿出一把枪瞄准好人,说时迟那时快,好人机警地察觉,为了自保于是将坏人一枪毙命。这个 Pattern 可以让好人有人性,又让坏人死有余辜。

床戏的 Pattern
不管和剧情有没有关系,编剧和导演总爱加上一段激情的床戏。这个 Pattern 相当困扰我和我的家人,因为每次看到这里,我们保守的一家人往往觉得很尴尬,我们所反应出来的 Pattern 是:借口倒茶水,上厕所,打电话 ... 而离座避风头 ... 但眼睛仍不时偷瞄。

恐怖片的 Pattern
无须我举例,电影惊声尖叫(Scream)第一集就为我们剖析出恐怖片的一大堆 Pattern。

公式化
好莱坞的电影比较多 Pattern,而欧洲的电影比较少 Pattern。至于昆丁塔伦提诺(Quentin Tarantino)编导的电影,完全是不按排理出牌,很难找到 Pattern。正因为好莱坞的电影很容易就可以找出 Pattern,所以常常会有似曾相似的感觉。许多人批评好莱坞的电影很「公式化」。
基本上,Pattern 就是一种公式化的表现。那么,究竟公式化是不是好事?

以艺术来说,公式化的结果会造成僵化,所以负面效果居多。电影号称是「第八艺术」,也是一种艺术创作,所以最好不要出现太多 Pattern,否则肯定被影评人痛批「了无新意」。
以工程来说,公式化是好事。这些公式都是「千锤百炼」的结果,运用这些公式可以确保工程具备一定的品质,并加快工程的进行。而软件开发也是一项工程,也需要尽量运用公式。 (软件另有需要艺术的一面,这不在本文的讨论范围)。

什么是 Design Pattern
所以,Pattern 就是一种「千锤百炼」的智能结晶。有经验的专家和没经验的新手,差别就在于:有经验的专家知道如何在适当的时机,套用某些公式(Pattern)以解决特定 的问题,这是专家经年累月所培养出来的 Know-How(请参见「软件产业的知识经济」一文)。

一般来说,对象导向软件开发的程序可以粗略分成 OOA(对象导向分析)、OOD(对象导向设计)、OOP(对象导向实作)。在 OOD(Object-Oriented Design)阶段所采用的 Pattern 就称为 Design Pattern。运用良好的 Design Pattern,可以使得系统架构更优良(也更快完成),对于后续的 OOP、测试、维护,都会有很大的 帮助。Design Pattern 会告诉你,什么情况下用 Delegation 而不要用继承、什么情况下用 Interface 而不要用 Class... 诸如此类的知识。这些都是软件界前辈的智能结晶。

我要强调 Design Pattern 专指 Design 时期的 Pattern。但是 Coding 时的 Pattern(例如程序代码内缩)最好不要称为 Pattern,以免混淆。Coding 时期的 Pattern 最好称为 Coding Style(或 Code Style)。

Design Pattern 这个名词也可沿用到许多地方。我认为孙子兵法就是一本军事领域 Design Pattern 的书,它告诉你什么时候该采什么样的军事动作。至于怎么去砍人,则是属于 implementation 的部分,不属于孙子兵法的范围。

什么是 Anti-Pattern
并非所有的 Pattern 都是好的,不好的 Pattern 称为 Anti-Pattern。如果你的系统中出现了 Anti-Pattern,就表示你犯了别人「常犯的典型错误」。简言之,Anti-Pattern 就是错误的示范,要尽量避免。

让 Design Pattern 成为你的不时之需
许多人在设计阶段才来喟叹:「 Pattern 到用时方恨少。」其实你可以避免这样的情况。现在市面上有许多本 Design Pattern 和 Anti-Pattern 的书。只要好好把这些书读过,体会每个 Pattern 的真正涵义,你可以在短短的时间内,功力激增一甲子。即使读过的 Design Pattern,如果比较少用,一阵子之后也可能会忘记。 所以最好能隔一阵子就把 Design Pattern 的书拿出来复习。

 
2008年02月22日 星期五 22:45

解百纳:

一种称作“解百纳”的干红葡萄酒,

市面上贴着“解百纳”标签的葡萄酒已多达30多种,

一瓶价格普遍在30元左右,也有便宜只卖10多元的,

而张裕葡萄酿酒股份有限公司的价格则要高得多。


张裕公司提供了“解百纳”的版本:

早在上个世纪30年代,

当时兼任张裕经理的中国银行行长徐望之先生,

组织一批公司和银行人员研究定名,

他们决定秉承张裕创始人张弼士倡导的“中西融合”理念,

取“携海纳百川”之意,

将这种高档葡萄酒命名为“解百纳干红”。

“解百纳干红”一直作为张裕的核心子品牌,

已有70多年的历史了。


但是,长城、王朝、威龙等企业有不同看法:

“解百纳”目前已经成为一个品种的通称,

如果这三个字为张裕所独有的话,

其他众多厂家必将大受影响。

他们认为,

“解百纳”一词是由法文“Cabernet”翻译而来,

“解百纳”并非张裕所独有。


“你们的干红葡萄酒为什么叫解百纳?”

“解百纳”是酿造这种酒所用的三种葡萄英文名称的缩写。

陈朴先解释说:“在国际上高档优质葡萄酒都是用葡萄品种命名的。

比如世界闻名的“雷司令”就是选用名为“雷司令”的葡萄为原料酿制而成的,

“解百纳”干红各项指标和风味完全达到了国际标准,

它吸收了三种葡萄的精华,故此而得名 ……”

精诚所至,金石为开。“解百纳”干红经国家批准,载入了中国葡萄酒的史册。

摘自1997年8月31日《经济日报》

PS:陈朴先(张裕公司的元老、酿酒专家、原副总工程师)


中国农学会葡萄分会的在京部分专家对此进行了座谈,

座谈会结果整理如下:

“解百纳”不是某一具体葡萄品种的正式名称。

“解百纳”一词是法文‘Cabernet’一词的音译。


在我国葡萄、葡萄酒界,

有时将“解百纳”作为赤霞珠(Cabernet Sauvignon)的别名,

也有将品丽珠(Cabernet Franc)、蛇龙珠(Cabernet Shelongzhu ,

原名称为Cabernet Gernischt)称为“解百纳”的,

或将“解百纳”作为这三个品种的通称。

它们是我国目前酿制干红葡萄酒的重要原料。


赤霞珠、品丽珠、蛇龙珠这三个品种酿制的葡萄酒具有相似的特点,

故可称为“解百纳”型葡萄酒。


赤霞珠是世界著名的红葡萄酒品种之一。

在美国四种最好的佐餐红葡萄中名列榜首。

上等的赤霞珠红酒需要在橡木桶中贮藏18-24个月之久才能装瓶出售,

赤霞珠在橡木桶的贮藏中,

酒体变得柔和、圆润、丰满、醇厚、协调,具有浓郁的果香,

酒呈深宝石红色,口味极佳。

在法国,酿酒师们常用品丽珠、梅鹿辄与其勾兑,以改善成品酒的典型性和风格。

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

一般葡萄酒的分类

一、按葡萄生长来源不同分类: l、山葡萄酒(野葡萄酒) 以野生葡萄为原料酿成的葡萄酒。产品以山葡萄酒或野葡萄酒命名。 2、家葡萄酒 以人工培植的酿酒品种葡萄为原料酿成的葡萄酒,产品直接以葡萄酒命名。 国内葡萄酒生产厂家大都以生产家葡萄酒为主。

二、按葡萄酒含汁量分类: 1、全汁葡萄酒 葡萄酒中葡萄原汁的含量为l00%,不另加糖、酒精与其他成份。例如干型葡萄酒。 2、半计葡萄酒 葡萄酒中葡萄原汁的含量达5明句,另一半可加入糖、酒精、水等其他辅料,例如半汁甜葡萄酒。

三、按葡萄酒的颜色分类: 1、白葡萄酒 选择用白葡萄或浅色果皮的酿酒葡萄。经过皮汁分离,取其果汁进行发酵酿制而成的葡萄酒,这类酒的色泽: 应近似无色,浅黄带绿,浅黄,禾杆 黄,金黄色。颜色过深不符合臼葡萄酒色 泽要求。 2、红葡萄酒 选择用皮红肉白或肉皆红的酿酒葡萄。采用皮、汁混合发酵,然后进行分离 陈酿而成的葡萄酒,这类酒的色泽应呈自然宝石红色。紫红色、石榴红色、失去自然感的红色不符合红葡萄酒色泽要求。 3、桃红葡萄酒 此酒是介于红、白葡萄酒之间。选用皮红肉白的酿酒葡萄,进行皮汁短时期混 合发酵达到色泽要求后进行分离皮渣,继续发酵,陈酿成为桃红葡萄酒。这类酒的 色泽应该是桃红色、或玫瑰红、淡红色。

四、按葡萄酒中含糖量分类: 1、干葡萄酒 酒的糖份几乎已发酵完,指每升葡萄酒中含总糖低于4克。饮用时觉不出甜味, 酸味明显。如干白葡萄酒、干红葡萄洒、干桃红葡萄酒。 2、半干葡萄酒 是指每升葡萄洒中含总糖在4一l2克之间。饮用时有微甜感,如半干白葡萄酒、半干红葡萄酒、半干桃红葡萄酒。 3、半甜葡萄酒 是指每升葡萄酒中含总糖在l2——50克之间。饮用时有甘甜、爽顺感。 4、甜葡萄酒 是指每升葡萄酒中含总糖在50克以上,饮用时有明显的甜醉感。

 
     
 
 
个人档案
 
w1a2r3

上次登录:
11天前
加为好友
 
   
 
文章分类
 
 
 
Mfc(6)
 
 
Cpp(3)
 
Xgn(1)
 
Com(1)
 
     
 
最新评论
   
文章评论|照片评论

     
 
好友最新文章
 
     
 
最近访客
 
 

chinazhsj

Icaoxiang

iamj_b

itaney

育英教科研博客

peruke

黑夜协奏曲

silenceshell
     
 
背景音乐
 
 
其它
 
已有人次访问本空间
 
订阅RSS  什么是RSS?

您也想拥有这样的空间?请点此申请。
     


©2008 Baidu