2008 Archives

nothingto.png
会上大家肯定会见到这个人!

(轉)Beautiful Code 书评

| No Comments | No TrackBacks

Beautiful Code 书评

重新擦亮思考的火花

原文: http://www.china-pub.com/37838 孟岩 

《代码之美》这本书已经成为经典。关于它本身的赞美之辞已经不少了,不过到底从这本书里该读些什么东西,我倒是有些思考。

上世纪九十年代初期,当时正在加州大学埃尔文分校攻读博士学位的Douglas Schmidt在观察了他所参与的软件项目开发实践之后,得出一个结论,即未来的软件开发将越来越多地体现为整合(integration),而不是传统意义上的编程(programming)。换言之,被称为 "软件开发者" 的这个人群,将越来越明显地分化:一部分人开发核心构件和基础平台,而更多地人将主要是配置和整合现有构件以满足客户的需求,类似现代汽车、机床和家用电器制造业的产业格局即将到来。面对这一前景,博士生Schmidt一方面写文章对于其进步意义大加赞扬,另一方面毫不犹豫地投入到核心构件及平台的开发阵营中去。他很清楚,在这样一种分工体系中,由于软件整合产业很难出现垄断局面,因此大多数利润总是被截留在上游,人当然要往高处走,整合是好事,但他老兄宁可让别人来做这个好事。


事实上,软件产业中大多数看上去挺靠谱的预测都被历史的发展无情地抛到垃圾堆里了,然而Schmidt博士生的这个预测却惊人的准确,其后十几年软件工业的发展完美地印证了他当年的判断。因此,他本人基于这一预测所选择的人生道路也一帆风顺。如今已经是教授的Douglas Schmidt先后创造了ACETAOCIAO等一系列分布式计算基础件,先后主导了美国学界和国防领域内若干重大科研与实际开发项目,称为世人公认的分布式计算架构领导者。


抛开他个人的辉煌不说,"整合化"趋势实际上已经深刻地改变了世界软件工业的面貌,从而也影响了身为晚进者的我们的命运。如今大部分的程序员实际上是在整合与配置现有资源以满足需求,而不是真正意义上的"编程"。这当然是一件好事,整合同样需要深刻的洞察力和创新精神,优秀的整合者与天才的程序员一样不可多得,甚至更加罕见。然而我们也不能不承认,大多数整合性的工作是机械的,简单的,重复的,欠缺创意的,深入的思考往往不必要。因此,在这个整合为王的时代里,思考的精神在钝化。更有甚者,互联网和搜索引擎的出现大大加速了这种钝化,几乎所有的问题都有人解决并且张贴在互联网上了,因此独自思考和解决问题已经成了不必要的、降低效率的行为,不但不时髦,而且不经济。软件开发迅速成为一个强调搜索和短期记忆力的技能,我想这是50年前第一代程序员们做梦也没有想到的。





老实讲,就整体而言,我仍然认为这是一种进步。任何一个产业的成熟,无不伴随着分工的明晰、技能的简化和从业门槛的降低。与少数人享受思考乐趣的需求相比,大多数人享受便宜而无处不在的软件服务的需求显然远为重要。但是,对于身处软件行业中的个体来说,思考力的削弱和丧失却是不折不扣的悲剧。这一点不必过多解释,正在苦苦寻找自己核心竞争力的开发者们都知道我说的是什么意思。几年来对中国开发者社群的近距离观察使我确信,尽管作为一个产业,中国软件一直享受着比较快的成长,但是总体而言,中国的软件开发者越来越迷惘、焦躁和不自信。这一情况当然是由多种原因导致的,但开发者们每念及此,多抱怨体制、产业、市场等身外之物,实在也有失偏颇。评心而论,这几年中国软件技术界的生存环境还是有了很大改善,对于那些真正出类拔萃的程序员来说,过上一种充实自信的生活并不困难。摆在每一个个体面前的主要问题还是在于能否出类拔萃,而这就需要我们重新找回思考的能力。具备强悍思考能力的人,也就具备强悍的解决问题的能力,而这样的开发者永远都是产业中的稀缺资源。


我认为这正是《代码之美》这本书的一个重要价值。合作的诸位大师级作者,给我们一个很好的机会,让我们能够一边阅读,一边思考,找回深思熟虑的智慧火花。这本书里所讲的每一个问题,可以说都是程序员在工作中会遇到或者至少会擦边的问题,既没有故弄玄虚的文字游戏,也没有携带了领域知识的私货,只有朴实而实际的一个个问题。虽然不是以提问的方式给出,但在整个阅读的过程中,我们还是能够找到很多机会与大师互动,不断地发现问题和解决问题。我在阅读中经常感到,看上去一个很简单的问题,却被这些大师们一层一层挖掘的如此深入,到最后阶段不由得令人感到战栗和震撼。看着这些智慧的光芒,我们不但可以领略大师之所谓称为大师的秘密,而且也认识到思考的真谛。因此,千万不要想看小说一样一带而过,那样会错过本书95%的价值!我们不是要阅读这些文字,而是要与文字背后的作者交流学习,一点一点把自己的心得记下来,对于作者提出的新问题,先自己思考,直接写程序尝试,争取跟上大师的思路,甚至可能需要反复几遍,才能真正读通这本书。这样的精力不会是白费的,读者应当认识到,当我们拥有这本书的时候,我们获得了怎样宝贵的机会,可以在相对比较短的时间里有效地提升自己的思考能力。这是一个机会,也是一次考验,我绝对相信,通过了这次考验的读者,会在思考和解决问题的能力上有一个大的进步。

我希望自己能够以这样的态度读这本了不起的书,以此文与其他读者朋友共勉之。

邊艾風

| 2 Comments | No TrackBacks
某友,最近身體不適.市場做惡夢.

某日,夢見一軍人,名曰"邊艾風"落難.
友冥思不得其解!

解夢:某友最近一直在編寫iphone App,那次夢的意識事,想變出一個iPhone供自己折騰.
        令一解釋:編(程)愛瘋,暗指自己喜歡愛瘋編程.

爱,唉,艾??

| No Comments | No TrackBacks
我只是不说话,
不是我故作潇洒,
也许人心太复杂,
让我感到害怕往事就忘了它吧,
为何你不肯作罢,
你不要说我是个无情的人,
说我不曾真正过也许就像是这么简单的一个字,
却占据了我生命所有重要的篇幅
别说我总是沉默,
别说我总是冷漠,
你又何必再触动我内心深处也许就像是这么简单的一个字,
却是我一生一世不能抛开的包袱
我也许一无所有,
至少我曾经拥有,
挂在嘴边的人如何体会,
我所谓的

OS X iPhone 2.1 真的来了

| No Comments | No TrackBacks
iphone2.1releasenote.png
看看Apple的工程师都解决了哪些Bug?好久以前就发过2.1 Beta版本的破解截图,印象中是10.5.4的kernel. 还没有功夫更新破解工具,估计是没啥问题,Downloading ipsw 中!

有序的混乱

| No Comments | No TrackBacks
"很多人的桌面处于'有序的混乱'状态,看起来乱糟遭的,但是它的主人可以很快地找到他要的东西.如果有人帮助他们清理,那才是害了他们呢"

好像就是在说我耶,我的桌面就是这样.如果你也这样,恭喜你,因为你的记忆很好,很快可以找到你需要的东西.

Parse XML Use ObjC

| No Comments | No TrackBacks

itemNodes = [doc nodesForXPath:@"ItemSearchResponse/Items/Item" error:&error];


doc 为NSXMLDocument boject,上面的语句的意思是按ItemSearchResponse-->Items--->Item

顺序查找Item,保存在NSArray itemNodes 

NSXMLDocument:An instance of NSXMLDocument represents an XML document as internalized into a logical tree structure. An NSXMLDocument object can have multiple child nodes but only one element, the root element. Any other node must be a NSXMLNode object representing a comment or a processing instruction. If you attempt to add any other kind of child node to an NSXMLDocument object, such as an attribute, namespace, another document object, or an element other than the root, NSXMLDocument raises an exception. If you add a valid child node and that object already has a parent, NSXMLDocument raises an exception. An NSXMLDocument object may also have document-global attributes, such as XML version, character encoding, referenced DTD, and MIME type.


- (NSString *)stringForPath:(NSString *)xp ofNode:(NSXMLNode *)n

{

NSError *error;

NSArray *nodes = [n nodesForXPath:xp error:&error];

if (!nodes) {

NSAlert *alert = [NSAlert alertWithError:error];

[alert runModal];

return nil;

}

if ([nodes count] == 0) {

return nil;

}

else    return [[nodes objectAtIndex:0] stringValue];

}

从NSXMLNode 使用nodesForPath 搜索 :

比如NSXMLNode"<Item><ASIN>0321503619</ASIN><DetailPageURL>http://www.amazon.com/Cocoa-Programming-Mac-OS-3rd/dp/0321503619%3FSubscriptionId%3D1CKE6MZ6S27EFQ458402%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0321503619</DetailPageURL><ItemAttributes><Author>Aaron Hillegass</Author><Manufacturer>Addison-Wesley Professional</Manufacturer><ProductGroup>Book</ProductGroup><Title>Cocoa(R) Programming for Mac(R) OS X (3rd Edition)</Title></ItemAttributes></Item>"

可以传入ASIN,DetailPageURL,Manufacture来取ASIN,URL,出版商.

NSXMLNode :Objects of the NSXMLNode class are nodes in the abstract, logical tree structure that represents an XML document. Node objects can be of different kinds, corresponding to the following markup constructs in an XML document: element, attribute, text, processing instruction, namespace, and comment. In addition, a document-node object (specifically, an instance of NSXMLDocument) represents an XML document in its entirety. NSXMLNode objects can also represent document type declarations as well as declarations in Document Type Definitions (DTDs). Class factory methods of NSXMLNode enable you to create nodes of each kind. Only document, element, and DTD nodes may have child nodes.

Access iPhone AddressBook code

| No Comments | No TrackBacks

翻翻以前的代码,留着用:

ABAddressBookRef book = ABAddressBookCreate(); 

CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(book);

CFIndex nPeople = ABAddressBookGetPersonCount(book);

NSMutableArray *masterList = [[NSMutableArray alloc] init];

for (int i = 0; i < nPeople; i++) {

ABRecordRef ref = CFArrayGetValueAtIndex(people, i);

CFStringRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);

CFStringRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);

CFStringRef phonenum=ABMultiValueCopyValueAtIndex(ABRecordCopyValue(ref,kABPersonPhoneProperty) ,0);

[masterList addObject:[NSString stringWithFormat: @"%@%@%@", (NSString *)firstName,(NSString *)lastName, (NSString *)phonenum]];


}

[masterList release];

测试代码:

    NSString *urlString =@"http://macgeeks.cn/index.php";

    NSURL *url = [NSURL URLWithString:urlString];

    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url 

                                                cachePolicy:NSURLRequestReturnCacheDataElseLoad

                                            timeoutInterval:30];

    NSData *urlData;

    NSURLResponse *response;

    NSError *error;

    char *buffer[40960];

    memset(buffer,0,sizeof(40960));


    urlData = [NSURLConnection sendSynchronousRequest:urlRequest

                                    returningResponse:&response

                                                error:&error];


    [urlData getBytes:buffer];   

    printf("%s\n",buffer);


WebServer Log:
211.144.218.2 macgeeks.cn - [08/Sep/2008:15:11:06 +0800] "GET /index.php HTTP/1.1" 200 6093 "-" "CFNetwork/330.4"

printf 显示的就是html,接下来就可以出来html了.
211.144.218.2 macgeeks.cn - [08/Sep/2008:15:17:04 +0800] "GET /index.php HTTP/1.1" 200 6093 "-" "CFNetwork/330.4"

Objective-C 关键词

| No Comments | No TrackBacks
 To minimize conflicts between C code and Objective-C code, Objective-C keywords are prefixed by @. Here are a few other Objective-C keywords: @end@implementation@class@selector@protocol@propertyand @synthesize

The following directives are used to declare and define classes, categories, and protocols:

Directive

Definition

@interface

Begins the declaration of a class or category interface.

@implementation

Begins the definition of a class or category.

@protocol

Begins the declaration of a formal protocol.

@end

Ends the declaration/definition of a class, category, or protocol.


 following mutually exclusive directives specify the visibility of instance variables:

Directive

Definition

@private

Limits the scope of an instance variable to the class that declares it.

@protected

Limits instance variable scope to declaring and inheriting classes.

@public

Removes restrictions on the scope of instance variables.

The default is @protected.

These directives support exception handling:

Directive

Definition

@try

Defines a block within which exceptions can be thrown.

@throw

Throws an exception object.

@catch()

Catches an exception thrown within the preceding @try block.

@finally

Defines a block of code that is executed whether exceptions were thrown or not in a preceding @try block.

In addition, there are directives for these particular purposes:

Directive

Definition

@class

Declares the names of classes defined elsewhere.

@selector(method_name)

Returns the compiled selector that identifies method_name.

@protocol(protocol_name)

Returns the protocol_name protocol (an instance of the Protocol class). (@protocol is also valid without (protocol_name) for forward declarations.)

@encode(type_spec)

Yields a character string that encodes the type structure of type_spec.

@"string"

Defines a constant NSString object in the current module and initializes the object with the specified 7-bit ASCII-encoded string.

@"string1" @"string2" ... @"stringN"

Defines a constant NSString object in the current module. The string created is the result of concatenating the strings specified in the two directives.

@synchronized()

Defines a block of code that must be executed only by one thread at a time.

Go On? Mac Development

| No Comments | No TrackBacks
不知道从什么时候开始喜欢编程.更不记得什么时候开始在Mac platform编程.最多也不过四年的事情吧,接触Mac差不多刚到四年.记得那个时候向自己撒了一个谎:"貌似可以写些程序在Mac上",可是现在看来,真是浪费. 我在Mac上都干过啥事情,好像没有正经像样子的,失败,真的很失败!还不如粉丝.

工作是一份和Mac一点不搭尬的工作,感谢我的老板,虽然他可能不会来看我的blog,感谢他帮助我完成参加WWDC的愿望.这份工作说不上喜欢,也不是那么很讨厌.虽然没有什么骄傲的成绩,只能"维持"生活而已.

回首刚刚过去的三年,不不,准确地说应该是两年+4个月,我就在工作和游戏之中度过.我希望下一份工作不属于游戏公司,不再为生活所迫.


你说我好不好?点啊

| No Comments | No TrackBacks
SonyVsApple.png

Who Know this man?

| No Comments | No TrackBacks
MrBig.png

由于需要download ImageKitStudy.zip ,故放狗找,找到不能下,用ssh -D 6666 root@onetwip 翻墙.
成功下载, So Groups Groups File have been HXed.

Learning CoverFlow

| No Comments | No TrackBacks
coverflow.png

- (void)awakeFromNib

{

_imageArray = [NSMutableArray new];

NSBundle * mainBundle = [NSBundle mainBundle];

        NSArray * imagePaths = [mainBundle pathsForResourcesOfType:@"jpg"

inDirectory:nil];

int count = [imagePaths count];

NSMutableArray *colorArray = [NSMutableArray arrayWithObjects:

  nil];


int i;

        for (i = 0; i < count; i++) {

             NSImage *image = [[NSImage alloc] initWithContentsOfFile:

     [imagePaths objectAtIndex:i]];

     [image lockFocus];

     [NSBezierPath fillRect:NSMakeRect(0., 0., 200., 200.)];

     [[NSString stringWithFormat:@"hello %d", [_imageArray count]] drawAtPoint:NSMakePoint(5., 5.) withAttributes:nil];

     [image unlockFocus];

     MyImageItem *item = [[MyImageItem alloc] initWithImage:image imageID:[NSString stringWithFormat:@"image-%d", [_imageArray count]]];

     [_imageArray addObject:item];

  

             [image release];

       }

       [u_imageBrowser setDataSource:self];

       [u_imageBrowser reloadData];

}


draw Polynomial

| No Comments | No TrackBacks
ooxxyy.png

 

-(void)drawInRect:(CGRect)b inContext:(CGContextRef)ctx

{

    NSLog(@"drawing");

    CGAffineTransform tf;

    tf = CGAffineTransformMake(b.size.width / funcRect.size.width, 0

                               0, b.size.height / funcRect.size.height

                               b.size.width/2, b.size.height/2);

    CGContextSaveGState(ctx);

    CGContextConcatCTM(ctx, tf);

    CGContextSetStrokeColorWithColor(ctx, color);

    CGContextSetLineWidth(ctx, 0.4);

    float distance = funcRect.size.width / HOPS;

    float currentX = funcRect.origin.x;

    BOOL first = YES;

    while (currentX <= funcRect.origin.x + funcRect.size.width) {

        float currentY = [self valueAt:currentX];

        if (first) {

            CGContextMoveToPoint(ctx, currentX, currentY);

            first = NO;

        } else {

            CGContextAddLineToPoint(ctx, currentX, currentY);

        }

        currentX += distance;

    }

    CGContextStrokePath(ctx);

    CGContextRestoreGState(ctx);

    

}

- (IBAction)createNewPolynomial:(id)sender

{    

    Polynomial *p = [[Polynomial alloc] init];

    [polynomials addObject:p];

    CALayer *layer = [CALayer layer];

    CGRect b = [[self layer] bounds]; 

    b = CGRectInset(b, MARGIN, MARGIN);

    

    CGPoint zeroPoint;

    zeroPoint.x = 0;

    zeroPoint.y = 0;    

    [layer setAnchorPoint:zeroPoint];

    

    [layer setFrame:b];

    [layer setDelegate:p];

    [layer setCornerRadius:12];

    [layer setBorderColor:[p color]];

    [layer setBorderWidth:3.5];

    

    [[self layer] addSublayer:layer];

    [layer display];

    CABasicAnimation *anim 

    = [CABasicAnimation animationWithKeyPath:@"position"];

    [anim setFromValue:[NSValue valueWithPoint:[self randomOffViewPosition]]];

    [anim setToValue:[NSValue valueWithPoint:NSMakePoint(MARGIN,MARGIN)]];

    [anim setDuration:1.0];

    CAMediaTimingFunction *f

    = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

    [anim setTimingFunction:f];

    [layer addAnimation:anim forKey:@"whatever"];

}


- (IBAction)deleteRandomPolynomial:(id)sender

{

    NSArray *polynomialLayers = [[self layer] sublayers];


    if ([polynomialLayers count] == 0) {

        NSBeep();

        return;

    }

    int i = random() % [polynomialLayers count];

    NSPoint toPoint = [self randomOffViewPosition];

    CALayer *layerToPull = [polynomialLayers objectAtIndex:i];

    CABasicAnimation *anim 

    = [CABasicAnimation animationWithKeyPath:@"position"];

    [anim setValue:layerToPull forKey:@"representedPolynomialLayer"];

    [anim setFromValue:[NSValue valueWithPoint:NSMakePoint(MARGIN,MARGIN)]];

    [anim setToValue:[NSValue valueWithPoint:toPoint]];

    [anim setDuration:1.0];

    CAMediaTimingFunction *f

    = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

    [anim setTimingFunction:f];

    [anim setDelegate:self];

    [layerToPull addAnimation:anim forKey:@"whatever"];

    [layerToPull setPosition:CGPointMake(toPoint.x, toPoint.y)];


}


Draw Line Use Cocoa

| No Comments | No TrackBacks
line_cocoa.png

    NSPoint bottom = NSMakePoint((bounds.size.width/2.0), 0);

    NSPoint bottom1 = NSMakePoint((bounds.size.width), 0);

    NSPoint bottom2 = NSMakePoint(0,(bounds.size.height));

//NSPoint bottom = NSMakePoint((0), 0);

    NSPoint top = NSMakePoint((bounds.size.width/2.0), bounds.size.height);

    NSPoint left = NSMakePoint(0, (bounds.size.height/2.0));

    NSPoint right = NSMakePoint(bounds.size.width, (bounds.size.height/2.0));

    [NSBezierPath setDefaultLineWidth:5];

//[NSBezierPath setDefaultLineWidth:<#(CGFloat)lineWidth#>];

    [[NSColor whiteColor] set];

    [NSBezierPath fillRect:bounds];


    [[NSColor redColor] set];

    [NSBezierPath strokeRect:bounds];

    //[NSBezierPath strokeLineFromPoint:top toPoint:bottom];

[NSBezierPath strokeLineFromPoint:top toPoint:right];

[NSBezierPath strokeLineFromPoint:top toPoint:left];

    //[NSBezierPath strokeLineFromPoint:right toPoint:left];

[NSBezierPath strokeLineFromPoint:bottom2 toPoint:bottom1];

[NSBezierPath strokeLineFromPoint:right toPoint:bottom];

[[NSColor blueColor] set];

    [[NSBezierPath bezierPathWithOvalInRect:bounds] stroke];