2014年1月14日 星期二

管理心得,三天三夜。。。

軟體、軔體開發的管理真的很難估算時程,而工程師也很難估算KPI(Key Performance Indicators, 關鍵績效指標),這些問題一直以來都存在,也都很難解決的了,接下來我就試著解決這個問題看看。

在計算KPI的時候需要一個基準的計量單位,而軟體、軔體個工程師應該用什麼東西當成計量的單位下去比較呢?

我給的方法是TASK,也就是任務,而這個任務不是單純把東西丟給工程師就沒事了,當控管的人需要切割TASK,讓工作份量範圍大概是三天左右(可以低,儘量不要高),估算這件事情就是「猜」,事實上,這種事情沒人說的準,而且當時程壓個一天也是在做,對工程師而言,一天搞不好也是可以完工,只是。。。沒測完全而已。

所以三天這個份量,說低也不低,說高也不高,以一周五個工作天來看,三天也去了大半,當事情超出預料,還可以多挪個兩天可以反應,要提早完成,就需嚴格檢查驗證是否仔細,當TASK的份量固定了之後,KPI才有依據,而對主管者來說能夠準確的切到三天份量的TASK,是個考驗,通常是先試試看,然後再來把結果回朔,用來調整預測值。

事情要是沒辦法切的好,是管理者的問題,如果管理者自身都沒能力理解這問題,自然就切不開,而可以理解之後,下刀的準度就是案子能不能順暢走完的關鍵。

當然訓練新人也需要一點組合技來加COMBO數(COMBO勒),一般來說沒意外的話,兩、三天之後應該就要有個產出,而過程中儘量的幫忙新人過關,不然的話很容易信心崩潰,這也很麻煩,所以在放TASK的時候也要注意TASK的難度,可以使用絕招「後向連鎖反應」的技巧(靠,這招用在需要特殊增強的特殊生都可能有用,一般人,哈哈哈),支持寫軟體的動力,最大部份還是來自「成就感」,一種對自我肯定的鴉片情感,所以要引誘新人吃這種鴉片,這招是最狠毒的絕招,當然啦,總是要先試用一下一般招式看能不能用,有些人一般招式就會中了,實在是沒必要出絕招,但是對於那種沒什麼信心、容易緊張卻實力還可以的新人,不得已,絕招還是得出,反正人都請進門了(誰叫你看錯人),不用也是浪費,況且本質上OK的人,只是個性上可能不屬於Ace王牌人才,也可能沒辦法穩定的零秒出手,當信心與習慣建立起來時,強度也是不容小覷的。

在每個回合當中,老手需要去糾正新手的習慣,事實上寫CODE在基礎訓練之後大部份都會(小部份不要問我怎麼辦,要轉、要丟隨便你),寫完之後好不好維護就另外一回事情了,所以糾正新人的習慣很重要,要不然全域變數把你搞一堆,一個原始碼的檔案破萬行,副程式都在比大、比肥的,關係搞得比三粒的電視劇還扯、還亂,還寫個鳥巢狀的超級迴圈考考你,這種CODE,考驗的不是你的技術或能力,是在考驗你的品性跟耐心,簡直就是在考驗你三字經什麼時候飆出來,所以切割一小段讓新人試試看,老鳥的糾正與驗收真的很重要。

一個習慣差的團隊在寫CODE,麻煩不是在能不能做出來,而是在往後到底能不能好好的維護,而有些人工作數十年,整個CODE的風格如一日,實在是浪費生命阿。

而當老闆的如果不是這行出身的,只想要出錢管人,或是放個外行的來管理,嘿嘿,兩相折磨之下,必有一傷,工程師會搞出很難維護的CODE,此後愈改愈慢,而且愈改愈難改,容易改東漏西的,問題愈來越發散,然後上下開始交怨,管的人不知道問題的複雜度,只知道老闆要的功能不多,改的人痛苦不堪,這個CODE牽一髮動全身,糾結難搞,還有點籌碼的能手,看到CODE就想閃人,新手接管之後是在浪費年輕生命來與盤根錯節的CODE搏鬥,這就是不尊重專業的下場。

所以尊重專業可以讓團隊順暢,節省時間,不尊重專業,問題會慢慢的沈澱,直到你港口阻塞,所有船都準備擱淺,重點還是在人身上。

而能夠俱備這等實力且能夠看穿真相的不是柯南,而是從工程師升級的架構師、設計師,從一般學校剛畢業就被學校教來搞SA、SD、SE的學生,絕大多數不俱備這種能力,除了邏輯上練習的程度差異之外,面對新手會遇到的問題與狀況,不是老手無法體會,而能夠在關鍵時刻給予新手點破的實力,也只有老手有機會做得到,當然這當中也要老手人品上沒問題,要是藏東藏西的,那就很難架構好的團隊出來。

所以建立一個優質的軟、軔體的團隊,事實上並不簡單。

2013年9月26日 星期四

新版的公開資訊觀測站還蠻機車的

新版的公開資訊觀測站基本上改版的很機車,既然是「公開」為什麼不友善一點把資料好好的給出來呢?

要搞一些鬼東西讓我們去PARSE,蠻討厭的。

http://www.twse.com.tw/ch/trading/exchange/MI_INDEX/genpage/Report201309/A11220130926ALLBUT0999_1.php?select2=ALLBUT0999&chk_date=102/09/26

http://www.twse.com.tw/ch/trading/exchange/MI_INDEX/genpage/Report[這個月YYYYMM]/A112[今天YYYYMMDD]ALLBUT0999_1.php?select2=ALLBUT0999&chk_date=[目標日期 YYY/MM/DD]

這樣看的懂嗎?

久一點的歷史資料就有點機車了,可能需要POST幫忙。
http://www.twse.com.tw/ch/trading/exchange/MI_INDEX/MI_INDEX_oldtsec.php?input_date=102/09/26&status=1


上市公司代號可以從這裡拿到
http://brk.twse.com.tw:8000/isin/C_public.jsp?strMode=2

上櫃公司代號可以從這裡拿到
http://brk.twse.com.tw:8000/isin/C_public.jsp?strMode=4

這裡可以拿到今天的交易CSV檔
http://mis.twse.com.tw/data/1101.csv

含最佳五檔
http://mis.twse.com.tw/stock_best5.html?stockId=1101

舊版的公開資訊觀測站資料還可以用
http://mopsov.twse.com.tw/server-java/t05st22?colorchg=1&off=1&TYPEK=sii&isnew=true&year=102&co_id=1101&ifrs=N&

這個網站可以拿到即時資料
http://dj.mybank.com.tw/sample/QueryRealTimePrice.asp?StockID=2317

這個文章的網址會抓出月報表
http://ithelp.ithome.com.tw/question/10128541?tag=rss.qu

除權息資料
http://www.twse.com.tw/ch/trading/exchange/TWT48U/TWT48U_PD.php?input_date=99/07/31&Sort_kind=&type=csv

這裡有python的demo code
http://pydoc.net/Python/grs/0.1.1/grs.realtime/

這個網址可以拿到休市的日期
http://www.twse.com.tw/ch/trading/trading_days.php


按照怪老子所說的鐘型理論
http://www.masterhsiao.com.tw/CatStocks/Stdev/Stdev.php

取得Yahoo的資料
http://ichart.finance.yahoo.com/table.csv?s=2412.TW&a=10&b=15&c=2000&d=08&e=26&f=2013&g=m&ignore=.csv

如果取得CSV的資料,的確有可能完成這個表

這個是取得本益比、殖利率與股價淨值比
http://www.twse.com.tw/ch/trading/exchange/BWIBBU/BWIBBU_d.php#&type=csv

http://www.otc.org.tw/ch/stock/aftertrading/DAILY_CLOSE_quotes/RSTA3104_1000902.csv

這是取得一些公司的基本資料參考網址
http://mops.twse.com.tw/mops/web/ajax_t51sb01?step=1&firstin=1&TYPEK=sii&code=01

Info資訊交流站會用python去取得資料
http://white5168.blogspot.tw/2012/08/python_12.html#.UkQSz9KBkto


2013年8月16日 星期五

人善被人欺,行程善呢?

在嵌入式系統上,使用System-V init來開機,有些kernel module需要載入,而又不希望整個系統開機看起來反應很慢,這時候怎麼辦呢?

或許利用Linux的多工處理是種方法,也就是說跟顯示、操作無關的有些kernel module丟到背景去執行,這樣就可以幾乎同時跑出你主要程式,可是此時,有個問題,當你載入kernel module的行程與你主程式的行程優先權是一樣的時候,也不見得可以快到哪裡去。

所以怎麼辦呢?

請載入kernel module的行程友善一點,把系統資源讓出來,主要程式要快點端出來讓使用者看看。

換成命令就是:
$nice -n 19 /etc/rc.d/loadDriver.sh

很簡單吧~~所以這行程非常的友善,把資源都讓出來了,你主要的程式當然是可以用力的給他跑到畫面出來,這樣的效果在我手邊的機器上可以差到將近五秒鐘,只是加了nice而已。


nice的使用可以參考鳥哥的網站。

事情難的都不是這命令怎麼用,而是你怎麼知道要改這個地方?

2013年8月15日 星期四

Core dump (核心轉儲)

核心檔案(core file),也稱核心轉儲(core dump),是作業系統在行程收到某些信號而終止執行時,將此時行程空間的內容以及有關行程狀態的其他訊息寫出到一個磁碟檔案。

核心檔案一詞源自於磁蕊記憶體 (core memory)

啟用core dump

大多數的Linux發行版通常會將core dump預設為關閉,此時要用ulimit命令可以查看目前的core dump功能是否有效。

$ulimit -c
0

-c 選項代表core dump文件的大小限制,上面例子限制為0,表示core dump是被關掉的。

開啟core dump

$ulimit -c unlimited

如此一來就設定為不限制core dump的大小,當發生問題的時候就會產生core file。

$./a.out
Segmentation fault (core dumped)

當下目錄會產生core file

$file core*
core.7561: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, format './a.out'

要用gdb除錯產生的core file

$gdb -c core.7561 ./a.out
GNU gdb Fedora (6.8-17.fc9)
...
Core was generated by './a.out'.
Program terminated with signal 11, Segmentation fault.
[New process 7577]
#0 0x000000000040048c in main () at segfault.c:6
6                     *a=0x1;



參考資料:
Book:Debug Hacks 深入除錯的技術和工具
Wiki :核心檔案


筆記Debug Hack 深入除錯的技術和工具

在這本書中提到有關程式異常結束時的對應方法
  • 程式異常結束
    • Kernel Panic?
      • NO  : SIGSEGV導致的?
        • NO  :其他原因 (HACK #5 ~ #7)
        • YES:記憶體非法存取 (HACK #26 ~ #30)
      • YES: Core Dump
        • NO  :設定了嗎?
          • 設定 (HACK #19 ~ #20)
          • 分析核心訊息 (HACK #38)
        • YES:原因分類 (Oops 消息 HACK #15)
          • 使用BUG() (HACK #35)
          • 偵測到異常 WDT (HACK #36 ~ #40)
          • 記憶體非法存取 (HACK #33 ~ #35)
  • 其他現象
    • degradation (HACK #41 ~ #42)
    • 記憶體洩漏 memory overlap (HACK #45、#46、$54)
  • 程式不結束
    • 核心有問題?
      • NO  : 負載高?(用top等調查)
        • NO  :死鎖 dead lock (HACK #31)
        • YES:死循環 (HACK #32)
      • YES: 設定了WDT了嗎?
        • NO  :WDT的設定方法 (HACK #22 ~ #23)
        • YES:SysRq鍵和minicom的用法 (HACK #16, #18)

2013年8月14日 星期三

關閉ERP的程式

有時候ERP授權是有限制的,通常那些用ERP的人為了怕等待,所以就把視窗一直開著,這就是所謂的「佔著毛坑不拉屎」的行為,導致後來要用的人根本連不上去,底下就是本人為了解決這個問題而試著寫的程式,當然路不只有一條。


#!perl
    use strict;
 use Win32::API;
    use Win32::GuiTest qw(:ALL);
 use File::HomeDir;
 
 my $maxLimit = 30; #second
 my $cmdName = "notepad.exe";
 my $counterFile = File::HomeDir->my_home."/counterFile.tmp";
 if(! -e "$counterFile"){
  system "ECHO 0 > \"$counterFile\"";
 }
 system "start ".$cmdName; #run command for testing
 #sleep 1;
 
 while(1){
  my $counter = `CAT \"$counterFile\"`; #read counter from counterFile.tmp
  chomp $counter;
  print "Counter is $counter\n";
  #To get foreground window handle
  my $hlWindow = GetForegroundWindow();
  #=========================================================================
  #To get PID via windows API
  Win32::API::->Import("user32","DWORD GetWindowThreadProcessId( HWND hWnd, LPDWORD lpdwProcessId)") or die $^E;
  my $pidLPDWORDStruct = pack( "L", 0 );
  GetWindowThreadProcessId($hlWindow, $pidLPDWORDStruct);
  my ($fwPid) = unpack ("L", $pidLPDWORDStruct);
  print "Foreground window PID is $fwPid\n";
  #=========================================================================
  
  my @taskList = `tasklist.exe`;
  
  my $targetPid=0;
  my $i=0;
  foreach my $line (@taskList){
   chomp $line;
   if($i > 4){
    my ($imageName, $pid, $sessionName, $session, $memUsage) = split /\ +/, $line;
    if($imageName =~ $cmdName){
     $targetPid = $pid; #save target PID
     if($pid == $fwPid){
      print $imageName."[".$pid."] --- foreground\n";
      system "ECHO 0 > \"$counterFile\""; #clear counter
      last; #break loop
     }else{
      print $imageName."[".$pid."] --- background\n";
      $counter++;
      system "ECHO $counter > \"$counterFile\""; #write to counterFile.tmp
      last; #break loop
     }
    }
   }
   $i++;
  }
  sleep(1);
  if($targetPid != 0 && $counter >= $maxLimit){
   system "taskkill.exe /pid $targetPid"; #kill process
   system "ECHO 0 > \"$counterFile\"";
  }
 }
 exit 0;

本人PO的原文

2013年8月9日 星期五

寫程式容易除錯難 II

在這一個行業混那麼多年了,這個是真是感觸很深,最近有個客戶把CODE丟到我手上,要我除錯,我花了一天想要建立環境,還要混到晚上等他起床,隔天大概花了不到一天的時間就查到問題所在,又是個Memory overlap的問題。

這老兄阿,顯示年月日的空間只要了七個字元的空間,扣除掉最後的c-string的結尾,前面只有6個字元而已。

下完底下這一行
sprintf(buffer,"%02d%02d%02d", bYY,bMM,bDD);

整個程式就瘋了,bYY因為RTC時間不正常,數值是226,記憶體一下子就overlap了,當然是吐出segmentation fault啦!

這看似很簡單的錯誤,這老美卻是把問題丟出來,DEBUG這回事有時候答案是很蠢,很簡單的錯誤,可是要找到這蟲阿,卻可能是個很複雜的過程。

今天發現有一個還不錯的東西等待研究Valgrind,這單字好像是英靈殿的入口,英靈殿(瓦爾哈拉Valhalla)是北歐神化中的天堂,掌管戰爭、藝術與死者的主神奧丁命令女武神(瓦爾基里Valkyrja)將陣亡的英靈戰士(恩赫里亞 Einherjar)帶來此服侍,這堆在日本動畫中出現的北歐神話字眼,都不是重點~~ㄎㄎㄎ。

Valgrind是在Linux下GPL V2的模擬除錯工具的集合,目前是還沒試過,相信也是有機會用的上,這一次我是用core dump的資訊去追出錯的地方,用的是老方法。

改天研究一下這個東西怎麼用~ㄎㄎㄎ(會用就進去英靈殿了)

參考資料:
IBM的文件
某人的部落格
WIKI說明