Thursday, December 19, 2013

Twice as much money don't make us twice as happy



可能是要開始進入上班族的日子,平時花錢如流水的我竟也開始想要了解理財之道,不外乎就是從小就聽到大的觀念,平時要省錢,不要亂花錢...
(我就說吧...我從小就沒什麼節流的觀念..所以這些話可能都聽了好幾遍了 = =)
到了這幾年,就常聽到說錢夠用就好的話,我以為大概就是過著像老子一樣的生活吧,沒什麼事業心,清清淡淡的,能身體健康地活著就好。
直到拜讀了J大的blog,看到了這句話: There is more to life than spending extra money to have some dude’s name on your underwear.
恩...這不就是名牌迷思嗎?!
我馬上就想到自己前陣子的確買了比平常去costco還貴的a&f四角褲..
我為什麼要讓這兩個人的命子出現在我四角褲上?! 對吼..果然想法轉個彎後,思路就不太一樣了..
但對於Twice as much money don't make us twice as happy,我想如果加倍之前的錢就已經蠻多了,那的確兩倍也就不必要了。 我預估我一天花個能花1000USD也就滿足了.. XD



src:
http://www.gocurrycracker.com/twice-as-much-money-wont-make-us-twice-as-happy/?fb_source=pubv1

Sunday, September 1, 2013

The Myth of the Genius Programmer


I've listed a few interesting note from my point of view

don't hide code, balance between spinning the wheel being lost and asking the person next to you every question that come into your head.

bus factor: having many people know the code in case the only person is hit by the bus, whether that bus comes in a form of a real bus or getting married, sick...
nobody sits down for thousands line of code before they compile...
u want other people see what u doing. you don't learn
"publish or perish"

give construct criticism. 
when failure comes, be ready for it. Document and learn.
fail faster so learn faster
practice 
don't try to be genious
collaborate early and often
brain crack: to roll out the idea
learn to be small fish, or looking around for big fish


http://www.youtube.com/watch?v=0SARbwvhupQ

Wednesday, August 28, 2013

“abandon all hope, ye who enter here.”

haha..this is a cool comment


I might mention that there is a dark side to using complex algorithms in software systems. The algorithms may not be understandable by others (or even the original author, after a long passage of time). I had incorporated some sophisticated regular expression pattern matching technology into AWK. Although it is documented in the Red Dragon book, Brian Kernighan once took took a look at the pattern-matching module that I had written and his only addition to that module was putting a comment in ancient Italian: “abandon all hope, ye who enter here.” As a consequence, neither Kernighan or Weinberger would touch that part of the code. I was the one that always had to make the bug fixes to that module!


can someone become a better programmer?
Al: My number one suggestion is to think before you program. Then I would advocate
writing lots of code, having experts critique your code, reading good code written by
others, and participating in code reviews. If you’re really brave, you could try to teach students to write good code.
... ...
I have certainly found that in every book that I have written with programs in it, the programs have gotten more efficient and shorter with the writing of the book. During the year we wrote the AWK book, many of the programs in it became 50% shorter. This is because we learned how to use the abstractions in AWK even more effectively than we initially had thought.

Thursday, July 4, 2013

Writing solid code


  • Enable all optional compiler warnings.
  • Lint.
  • Maintain both ship and debug versions of your program.
  • Use assertions to validate function arguments.

#ifdef DEBUG
    void _Assert(char*, unsigned); /*prototype*/
    #define ASSERT(f)\
      if(f)          \
        {}           \
      else           \
        _Assert(__FILE__, __LINE__)

#else
    #define ASSERT(f)
#endif

void _Assert(char *strFile, unsigned uLine)
{
  fflush(NULL);
  fprintf(stderr, "\nAssertion failed: %s, line %u\n", 
           strFile, uLine);
  fflush(stderr);
  abort();
}



  • Strip undefined behavior from your code, or user assertions to catch illegal users of undefined behavior.
  • Don't waste people's time. Document unclear assertions.
/* Blocks overlap? Use memmove. */
ASSERT(pbTo>=pbFrom+size || pbFrom >= pbTo+size);
  • Either remove implicit assumptions, or assert that they are valid.
  • Use Assertions to detect impossible conditions.
  • Don't hide bugs when you program defensively.
  • Use a second algorithm to validate your results.
implement an ASSERT macro that the file name string(__FILE__) would be defined just once per file:
bury the details in a new ASSERTFILE macro that you use once at the start of each source file


  #ifdef DEBUG
    #define ASSERTFILE(str)    \
              static char strAssertFile[] = str;

    #define ASSERT(f)          \
              if(f)            \
                {}             \
              else             \
                _Assert(strAssertFile, __LINE__)
  #else
    #define ASSERTFILE(str)
    #define ASSERT(f)
  #endif
  • Eliminate random behavior. Force bugs to be reproducible.
#define bGarbage 0xA3
flag fNewMemory(void **ppv, size_t size)
{
  byte **ppb=(byte**)ppv;
  ASSERT(ppv!=NULL && size!=0);
  *ppb=(byte*)malloc(size);
  #ifdef DEBUG
  {
     if(*ppb != NULL)
       memset(*ppb, bGarbage, size);
  }
  #endif
  return (*ppb != NULL);
}
  • Destroy your garbage so that it's not misused.
  • If something happens rarely, force it to happen often.
Once you release memory, you don't own it, so you shouldn't touch it.
(some memory managers use free memory to store free-chain information, or other internal implementation data) Programmers either don't know, or regularly forget, that realloc can move blocks. Detecting this problem is important. =>
Stimulate what realloc does:
If the block is shrinking, pre-fill the soon-to-be released memory. If the block is expanding, force it to move(instead of expanding in place) by faking a realloc. If the block is the same size, don't to anything.

Remember that debug code is extra code, not different code. Unless there is a compelling reason not to, you should always execute the ship code, even if it's redundant.
  • Keep debug information to allow stronger error checking.
  • Design your test carefully, nothing should be arbitrary.
Choosing a value for bGarbage, recursed over the symbol table's tree structure with a pre-order traversal. Some choices are better than others.
  •  Setting "undefined" memory to a constant garbage value is one example of removing random behavior.
  • Make sure your tests work even for programmers who are unaware of them. The best tests are those that require no knowledge of their existence.
Programmers occasionally write coe that fills past the end of an allocated memory block. How you could enhance the memory subsystem checks to alert you to these types of bugs.

Allocate 1 extra byte for every block that you allocate: 檢查DebugByte有沒有被覆寫過去

#define dDebugByte 0xE1

#ifdef DEBUG
  #define sizeofDebugByte 1
#else
  #define sizeofDebugByte 0
#endif

flag fNewMemory(void **ppv, size_t size)
{
  byte **ppb = (byte**)ppv;
  ASSERT(ppv!=NULL && size !=0);
  *ppb = (byte*) malloc(size+sizeofDebugByte);

  #ifdef DEBUG
  {
    if(*ppb!=NULL)
    {
      *(*ppb+size)=dDebugByte;
      memset(*ppb, bGarbage, size);
      .
      .
      .


flag fResizeMemory(void **ppv, size_t sizeNew)
{
  byte **ppb = (**byte) ppv;
  byte *pbNew;
  .
  .
  .
  pbNew = (byte*)realloc(*ppb, sizeNew+sizeofDebugByte);
  if(pbNew!=NULL)
  {
    #ifdef DEBUG
    {
      *(pbNew+sizeNew)=dDebugByte;
      .
      .
      .


/* Verify that nothing wrote off end of block. */
ASSERT(*(pbi->pb + pbi->size) == dDebugByte);

how could you give testers the ability to fake out-of-memory conditions?
Normally by using a tool to gobble memory until the application's memory requests begin to fails.
It works, but not very precise --- it cause some allocation request somewhere in the program fail.
A better technique is to build an out-of-memory simulator directly into the memory manager.
在newMemory時,或在resizeMemory時,add an if statement

#ifdef DEBUG
  if(fFakeFailure(&fiMemory))
  {
    *ppb=NULL;
    return (FALSE);
  }
#endif

With these changes, the failure mechanism is in place. To make it work, you would call the SetFailure routine to initialize the failureinfo struct:

/* tell the failure system that you want to call the system five times before getting seven consecutive failures. */
SetFailures(&fiMemory, 5, 7); 

/* tow common calls to SetFailures: Don't fake any failures. Always fake failures */
SetFailures(&fiMemory, UNIT_MAX, 0);
SetFailures(&fiMemory, 0, UNIT_MAX);


The code below implements the four functions that make up the failure mechanism.

typedef struct
{
  unsigned nSucceed; /* # of calls before failing */
  unsigned nFail;    /* # of times to fail        */
  unsigned nTries;   /* # of times already called */
  int lock;          /* if > 0, disable mechanism.*/
} failureinfo;

void SetFailures(failureinfo *pfi, unsigned nSucceed, 
                  unsigned nFail)
{
  /* If nFail is 0, require that nSucceed be UNIT_MAX. */
  ASSERT(nFail != 0 || nSucceed == UINT_MAX);

  pfi->nSucceed = nSucceed;
  pfi->nFail    = nFail;
  pfi->nTries   = 0;
  pfi->lock     = 0;
}

void EnableFailures(failuresinfo *pfi)
{
  ASSERT(pfi->lock > 0);
  pfi->lock--;
}

void DisableFailures(failuresinfo *pfi)
{
  ASSERT(pfi->lock >=0 && pfi->lock < INT_MAX);
  pfi->lock++;
}

flag fFakeFailure(failureinfo *pfi)
{
  ASSERT(pfi != NULL);
  if(pfi->lock > 0)
    return (FALSE);

  /* Pin nTries at UINT_MAX. */
  if(pfi->nTries != UINT_MAX)
    pfi->nTries++;

  if(pfi->nTries <= pfi->nSucceed)
    return (FALSE);

  if(pfi->nTries - pfi->nSucceed <= pfi->nFail)
    return (TURE);

  return (FALSE);
}

  • Don't wait until you have a bug to step through your code
  • Step through every path (more than one code path: if and switch statements, &&, || and ?: operators)
  • As you step through code, focus on data flow ( Overflow and underflow bugs, Data conversion bugs, Off-by-one bugs, NULL pointer bugs, Bugs using garbage memory(oxA3 bugs), Assignment bugs in which you've use = instead of ==, Precedence bugs, Logic bugs, )
  • Source leve debuggers can hide execution details. Step through critical code at the instruction level.
  • Bugs don't grow in code spontaneously; they are the result of a programmer's writing new code or changing existing code. If you want to find bugs in your code, there is no better method than stepping through eery line of the code the moment it's compiled.
  • The problem with black-box testing is that you can't tell what goes on between stuffing in the inputs and receiving the outputs. The best way to catch bugs is to look for them the moment you write or change code. I don't know how many programmers who consistently write bug-free code, but the few I do know habitually step through all of their code

  • Make it hard to ignore error conditions. Don't bury error code in return values.
  • Always look for, and eliminate, flaws in your interfaces.
  • Don't write multipurpose functions. Write separate functions to allow stronger argument validation. 
  • Don't be wishy-washy. Define explicit function arguments.
getchar returns int
realloc return null (Ideally, realloc would always return an error code and a pointer to the memory block  regardless of whether the block was expanded.)

/* the if statement in the code ensures that the original pointer is never destroyed. */

flag fResizeMemory(void *ppv, size_t sizeNew)
{
  byte **ppb = (byte**) ppv;
  byte *pbNew;
  
  pbNew = (byte*) realloc(*ppb, sizeNew);
  if(pbNew!=NULL)
    *ppb=pbNew;
  return (pbNew!=NULL);
}



  • Write functions that, given valid inputs, cannot fail.
Implement standard tolower function to "return the lowercase equivalent of ch if one exist; otherwise, return the character unchanged" If you find that you can't eliminate error condition, consider disallowing the problematic cases altogether. use an assertion to verify argument.


char tolower(char ch)
{
  ASSERT(ch>='A' && ch<='Z');
  return (ch+'a'-'A');
}



  • Make the code intelligible at the point of call. Avoid boolean arguments.
UnsignedToStr(u, str, TRUE);
UnsignedToStr(u, str, FALSE);
=>
#define BASE10 1
#define BASE16 0
UnsignedToStr(u, str, BASE10);
UnsignedToStr(u, str, BASE16);
=>
void UnsignedToStr(unsigned u, char *str, unsigned base);

  • Write comments that emphasize potential hazards.

/* getchar -- equivalent to getc(stdin).
 *
 * getchar returns the next character from stdin. When
 * an error occurs. it returns the *int* EOF. A typical 
 * use is
 * 
 *   int ch;  //ch *must* be an int in order to hold EOF.
 * 
 *   if ((ch=getchar())!=EOF)
 *     //success
 *   else
 *     //failure
 */

int getchar*void)
...

/* realloc(pv, size)
 * ...
 * 
 * A typical use is
 * 
 *   void *pvNew;  //used to protect pv if realloc fails
 *   pvNew = realloc(pv, sizeNew);
 *   if(pvNew!=NULL)
 *   {
 *      //success --update pv
 *      pv=pvNew;
 *   }
 *   else
 *      //failure -- don't destroy pv with the NULL pvNew
 */

void *realloc(void *pv, size_t size)
...

why is the ANSI strncpy function bound to trip up the unwary programmer?
Sometimes strncpy terminates the dest str with a nul character, and sometimes it doesn't.

C++'s inline function specifier is valuable because it allows you to define functions that are as efficient as macros yet don't have the troublesome side effects that macro "functions" have in evaluating their parameters.

The serious problem with C++'s new & reference arguments is that such arguments hide the fact that you are passing the variable by reference , not by value, and that can cause confusion. For example, suppose ou redefine the fResizeMemory function so that it uses a reference argument. Programmers could then write
if( fResizeMemory(pb, sizeNew))
   resize was successful
But notice, programmers unfamiliar with the function would have no reason to believe that pb might be changed during the call. How do you think that will affect program maintenance?
A related concern is that C programmers often manipulate the formal arguments to their functions because they know those arguments are passed by value, not reference  But consider the maintenance programmer who fixes a bug in a function he didn't write. If that programmer fails to notice the & in the declaration  he could modify the argument without realizing that the change won't be local to hide function . & reference arguments are risky because they hid an importnat implementation detail. 

Monday, February 11, 2013

quote and reading

“Obstacles are those frightful things you see when you take your eyes off your goal.” - Henry Ford

“Great spirits have always encountered violent opposition from mediocre minds.” - Albert Einstein

“Knowing is not enough; we must apply. Willing is not enough; we must do.” - Goethe

“It's kind of fun to do the impossible.” - Walt Disney

“Live the life you've dreamed” - Henry David Thoreau

Look for passion. Smart people are passionate about the projects they work on. They get very excited talking about the subject. They talk quickly, and get animated

從一月十四開學到現在也快一個月了,從台灣剛來的時候雖然累但是上課還算得上專注,現在不到一個月已經有漸漸習慣的跡象,不好,剛來的目標跟憧憬漸漸地被掩蓋,一定要更專注於目標,是身邊的人讓我這樣感覺,還是環境,這條路還是一樣未知...

http://www.troyhunt.com/2013/02/the-ghost-who-codes-how-anonymity-is.html
http://www.joelonsoftware.com/
[REF:http://dudye.com/get-in-to-action-77-thoughts-on-motivation/]

George Polya's quote
"To be a good mathematician, or a good gambler, or good at anything, you must be a good guesser"


The simplest solution is to act


watch your thought, for they become words
watch your words, for they become actions
watch your actions, for they become habits
watch your habits, for they become character.
watch your character, for they become destiny


When you get into a tight place and everything goes against you, till it seems as though you could not hang on a minute longer, never give up then, for that is just the place and time that the tide will turn.

~Harriet Beecher Stowe

Saturday, January 12, 2013

大學生知道了沒

你學到了什麼,比你拿幾分更重要

何謂成功 何謂失敗

Thought on success: http://www.thecrimson.com/article/2009/2/23/thoughts-on-success-students-can-be/
Students can be very tough on themselves. It concerns me that some carry a very narrow definition of success and others see asking for help as a sign of weakness. Years ago, freelance writer Linda Weltner shared the following story attributed to Norris Lee in The Boston Globe: 

A lecturer stands in the front of a class of overachievers, holding a 1-gallon wide-mouth mason jar. He fills it with good-size rocks, then asks the group, “Is this jar full?” The audience agrees that it is. 

“Oh, really?” he asks. He pours in several handfuls of gravel. “Is the jar full now?” The audience is doubtful. Probably not. He pours a handful of sand into the jar, filling it to the brim. “How about now?” he asks. Not yet. He pours in a pitcher of water. 

“OK,” he asks. “What’s the lesson to be learned here?” 

“Well,” says a man sitting near the front, “you’ve just demonstrated that no matter how full your schedule is, you can always fit more in.” 

“You’re absolutely wrong,” says the teacher. “The point I’m making is that if you don’t put the rocks in first, you’ll never get them all in.” 

This story says a lot about success. Harvard educators have more than education as a job; they must help students identify what the “rocks” in their world are at any point. By “rocks,” I mean the things a student wants to place high priority on when assessing progress made or distance still to go. Students want to be successful, but too often they see success in a limited way (for instance, a near flawless transcript) or they don’t really know what they are working toward. 

In high school, it was simpler. Students pushed to assemble records that would get them into top colleges. With tougher competition in college, it becomes more difficult to achieve the near flawless transcript. And, with many more post-graduate options, it is difficult to feel a clear sense of direction. 

In the past, when I have asked advisees what they want to be sure gets into the jar, or what they will use as a marker of success, they have thought hard. Some responses come to mind: I want to feel like I fit in personally and have one or two really good friends; I want to make strong progress in identifying a concentration; I want to interview my grandmother, whose health is failing, in order to begin to write a memoir. These responses have given the students a personal compass and a chance to look back at the end of the year with—more often than not—a sense of accomplishment and self-worth. That awareness has mattered hugely. 

My second concern is about the act of asking for help. Clarissa Pinkola Estes, a poet and psychoanalyst, made the following statement: “Asking the proper questions is the central action of transformation. Questions are the key that causes the secret doors of the psyche to swing open.” I know that it can be hard to ask questions or to acknowledge that you don’t have the answers that appear critical to move forward. But, it is important to remember that this is a complicated place and this is a complicated period of one’s development. We think more—not less—of students who ask questions and who take advantage of the myriad resources and support services here. Doing so suggests a kind of agency or taking charge that is both appropriate and applaudable and that contributes significantly to the achievement of success.


行使你的教育自主權:

從接受的角色轉換為主張的角色
如果你能用熱忱與殷切的好奇心去學習,自然能完成那些達到好成績之前,所必須要的苦差事
善用教授們訂出的輔導時間
與教員們密切聯繫 : 在哪些課堂上較可能與教授建立私交?可以主動挑選這種課
在教室以外的地方開啟與faculty的學術對話/非學術對話
握有學習的主控權,進行策略性的思考,展現你的自制力,小心審慎哪些事重點,該在何時完成
懂得方法的學生不會試著把所有東西都塞進腦子裡,以為這樣就可以好好吸收,而是選擇特定的學習方式,屆此管理自己所吸收的資訊。在念書時,為什麼我要念這些東西?我從中應該學到什麼?他們能幫我回答什麼問題?透過我的學習與練習將來我有辦法解決什麼難題?

邁向成功的三個關鍵:
設定個人目標
培養學習策略
做計畫(找出阻礙你的原因,並且把它排除掉)

時間管理並不只是跟避免拖拖拉拉有關,他的經隨是,你必須主動管理,你怎樣使用時間這種最珍貴的資源。分析你是怎麼消耗掉一整天的。估算一下自己在一週之內做了哪些事。打開一個你自製的電子表格,在左邊欄位列出以半小時為單位的時間,頂端列出七欄代表七天。寫下你覺得在哪個時間點應該要做的事。把每件事花了多少時間都寫下來上課練習吃飯與同學碰面上網逛臉書睡覺。不要有所遺漏,包括運動玩樂看電視,在這些活動之間,你必須插入25~35小時的空檔溫習功課。
第二步驟是精確記入實際做的事情,當然不會百分百一樣誰都有發呆分心的時候,人生也有許多無法預期與計畫之外的事。重點是看出你與理想的計畫相差多遠。

提早一點起床,在上課前念書或溫習筆記,如果課堂間有一小時空檔,他們會坐下來念書而不是喝咖啡,聊天發呆。我認識的一些最有成就的學生,他們把白天時間當成在上班。這種觀念跟校園文化相反,大部分學生都是晚上七點才開始念書,然後一直念過午夜,如果你平均一天上三小時的課,那麼你等於是把八小時的白天時間浪費在學業以外的事情上面。你可以先把工作做完,然後好好享受剩餘的時光。

問你的授課老師,他們對於修課學生會提出哪些學習建議,請教那些跟你修同一門課但是表現較好的同學,問他們是怎樣吸收教材的。

把問題寫下,期中考試題也袋了,圈出他還不懂的地方,他先想好要做些什麼,把問題以及他不懂的一些關連列出來,大衛讓教授可以把注意力擺在一組特定的問題上,事後他可以獲得更多了解教材的洞見,

Friday, January 11, 2013

三本很受啟發的書

Outliers: the story of success
好上加好的馬太效應
一萬小時的努力
天才的迷思

上哈佛學到的事
每天讀四個小時的書,然後睡五個小時的覺。其他時間就去練舞或是練舞台劇。
就算是結果相同的事,也要做的與眾不凡。
追求最好的,盡最大的努力。而且一開始就要為了盡最大努力追求最好而祈禱。
想要有效率讀書,第一步就是要保留一段不受他人妨礙,數個小時的完整讀書時間。
和教授親近
真正的自信,是來自於將困難克服的那一刻。一再挑戰自己的極限,也將自己的能力做最大的延伸。
所謂不可能是不努力的人找的藉口
brown bag lunch
將時間好好安排,做真正想做的事情(像一間吃到飽餐廳,如果傻傻地想到什麼就吃什麼,很有可能會吃壞肚子,或是塞進一堆沒營養的東西,等看到真正美味的食物時,大概也吃不下了)
在哈佛待了一年之後,我用不同的角度審視我自己。以前的我只希望有所不同,希望變得更好,但卻不知道應該先從改變自己開始。每年都在同一塊土地上撥下相同的種子,用同樣的方式耕種,然後奢望今年比往年更豐收,簡直像個懶惰又貪心的農夫,如果每年都種一樣的農作物,久了地力就會逐漸損耗,這時就要採取休耕或是轉種其他作物,一直到地力恢復為止,這是另一種意義的領土擴張。用更具創意及生產立的方式來開發既有的土地,這點遠比擴大佔地更重要。也因此,一定要懂嘗試用不同的角度來看待相同的事物,只有想法改變,並不會讓結果有所不同。必須在行動及生活習慣上做改變,才可能有不同的結果。我們應該練習如何努力才能達成願望。
努力也是需要練習的,嘗試過的人才知道如何努力,光有決心是不夠的,
成就也一樣,要先知道如何成就小事,這樣才有可能成就大事

Talent is overrated. What really separates world-class performers from everybody else
我比別人更認真 刻意練習 讓自己發光
刻意練習是專為突破現狀,更上層樓而設計的活動,他挑戰你的心智,需要教練從旁協助
多年密集的刻意練習訓練會改造身體和大腦,讓卓越者比多數人感知更多,知曉更多,記憶更多
確知目標和方向:顯而易見卻值得深思的第一步:在於知道你想做什麼,這裡的關鍵字不是什麼,是知道。卓越之路需要經理多年的嚴苛考驗,若非全心全力投入,誰都不可能達成。你比需明確知道你想要做什麼,而不是覺得,傾向或考慮自己要做什麼
自發練習必須集中在上午,由於練習如此辛苦,這些小提琴家必須精確安排固定作息時間才能大量練習