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說明

2013年7月3日 星期三

寫程式容易除錯難

之前在討論22k,還有一些機車的公司用低價僱用年輕的程式設計師,我覺得很多老闆腦袋都有問題,在軟、軔體或系統的程式設計領域上,價值是與解決事情的效率成正比,高學歷、名牌學校,不見得會比較有價值,有些時候程式人人都會寫,除了巧妙差異之外,還有除錯能力上的差異,有些年輕人遇到問題實在解不了,埋起來或是乾脆換工作都大有人在,也有人寫了一個很難維護程式碼,難到連他自己本人都維護不了,出現的鬼問題也非常的藝術,若隱若現的,這也造成市場上有關這方面的工作需求,很多時候不太喜歡用新人,也不太考慮學歷的問題,在104的統計上薪資增長速度與工作的年資比較有關係,學歷差異上到大學之後就沒長進了,軟體上甚至倒退,結果是碩士生拿到比較低的價碼。

最近有個BUG是有史以來遇到最機車的,這隻蟲非常、非常、非常、、、偶爾才會出來搗蛋,可是一旦出現,整個系統就幾乎停擺,剩下中斷還活著,很湊巧是客戶的程式執行的時候會產生,也很不幸的是到客戶手上才被發現,而當認真寫個小程式去複製這個問題的時候卻又碰不到,也就是只有客戶的那隻程式在十分的湊巧才會撞見,碰到的機率要不快、不慢,不是猛呼叫會加速碰到的機率,而他出現的平均時間又很尷尬,五到八小時,我好不容易拿著客戶的原始碼調到兩個時左右,可是我按照客戶的邏輯直接呼叫函式猛叫,反而怎麼跑都出不來。

解決這個死結的問題,靠的是SysRq,利用中斷去倒出當時系統執行了哪些thread、process,以及call stack。

底下就是SysRq拿到的LOG
[ 2676.460000] events/0      R running      0     4      2 0x00000000
[ 2676.460000] Backtrace:
[ 2676.460000] [<c03f52d0>] (schedule+0x0/0x370) from [<c03f571c>] (preempt_schedule_irq+0x48/0x7c)
[ 2676.460000] [<c03f56d4>] (preempt_schedule_irq+0x0/0x7c) from [<c00279a8>] (svc_preempt+0x8/0x20)
[ 2676.460000]  r4:ffffffff
[ 2676.460000] [<bf00e2a0>] (K_UARTTxReadyEx+0x0/0x64 [cadrv]) from [<bf02b780>] (_MAP_RegGetData+0xc0/0x20c [cadrv])
[ 2676.460000] [<bf02b6c0>] (_MAP_RegGetData+0x0/0x20c [cadrv]) from [<bf02bc5c>] (CLR_SetBitData+0x38/0x94 [cadrv])
[ 2676.460000]  r7:c3027ef7 r6:00000001 r5:00000020 r4:00000000
[ 2676.460000] [<bf02bc24>] (CLR_SetBitData+0x0/0x94 [cadrv]) from [<bf0298f0>] (K_BatterySendPowerSwitch+0x30/0x5c [cadrv])
[ 2676.460000]  r7:bf0c79fa r6:bf0c79f5 r5:00000001 r4:00000001
[ 2676.460000] [<bf0298c0>] (K_BatterySendPowerSwitch+0x0/0x5c [cadrv]) from [<bf02a1ec>] (K_Battery_Power_Switch+0x1ec/0x2e0 [cadrv])
[ 2676.460000]  r6:bf0c7a2f r5:00000000 r4:00000002
[ 2676.460000] [<bf02a000>] (K_Battery_Power_Switch+0x0/0x2e0 [cadrv]) from [<c00574f8>] (run_workqueue+0xc4/0x1e4)
[ 2676.460000]  r7:c3027f94 r6:c3001820 r5:c3026000 r4:bf0c7a6c
[ 2676.460000] [<c0057434>] (run_workqueue+0x0/0x1e4) from [<c0058288>] (worker_thread+0x9c/0x120)
[ 2676.460000] [<c00581ec>] (worker_thread+0x0/0x120) from [<c005c228>] (kthread+0x88/0x90)
[ 2676.460000]  r7:00000000 r6:c00581ec r5:c3001820 r4:c301bef0
[ 2676.460000] [<c005c1a0>] (kthread+0x0/0x90) from [<c0042ab8>] (do_exit+0x0/0x2ec)
[ 2676.460000]  r6:00000000 r5:00000000 r4:00000000

[ 2676.460000] AppMan        R running      0   888    759 0x00000002
[ 2676.460000] Backtrace:
[ 2676.460000] [<c002b8f4>] (dump_backtrace+0x0/0x118) from [<c002ba28>] (show_stack+0x1c/0x20)
[ 2676.460000]  r6:00000000 r5:c2b80680 r4:c2b80680
[ 2676.460000] [<c002ba0c>] (show_stack+0x0/0x20) from [<c0036680>] (sched_show_task+0xac/0xe4)
[ 2676.460000] [<c00365d4>] (sched_show_task+0x0/0xe4) from [<c0037d6c>] (show_state_filter+0x6c/0xb8)
[ 2676.460000]  r5:c2b80680 r4:c2b80680
[ 2676.460000] [<c0037d00>] (show_state_filter+0x0/0xb8) from [<c0213e38>] (sysrq_handle_showstate+0x18/0x1c)
[ 2676.460000]  r8:00000074 r7:60000193 r6:c2b82000 r5:00000001 r4:c056e96c
[ 2676.460000] [<c0213e20>] (sysrq_handle_showstate+0x0/0x1c) from [<c0213c78>] (__handle_sysrq+0xa8/0x198)
[ 2676.460000] [<c0213bd0>] (__handle_sysrq+0x0/0x198) from [<c0213de8>] (handle_sysrq+0x34/0x38)
[ 2676.460000] [<c0213db4>] (handle_sysrq+0x0/0x38) from [<c0219100>] (bcm5892uart_rx_chars+0x1dc/0x2ec)
[ 2676.460000]  r5:00010074 r4:c056ec78
[ 2676.460000] [<c0218f24>] (bcm5892uart_rx_chars+0x0/0x2ec) from [<c02197a8>] (bcm5892uart_int+0x94/0xe8)
[ 2676.460000]  r8:00000000 r7:c2b82000 r6:000000ff r5:c056ec78 r4:00000040
[ 2676.460000] [<c0219714>] (bcm5892uart_int+0x0/0xe8) from [<c0076944>] (handle_IRQ_event+0x78/0x1e0)
[ 2676.460000]  r7:00000046 r6:c31b2920 r5:c2b82000 r4:c31b2920
[ 2676.460000] [<c00768cc>] (handle_IRQ_event+0x0/0x1e0) from [<c0079434>] (handle_level_irq+0xa8/0x160)
[ 2676.460000] [<c007938c>] (handle_level_irq+0x0/0x160) from [<c002506c>] (asm_do_IRQ+0x4c/0x94)
[ 2676.460000]  r7:00000002 r6:00000000 r5:c056a094 r4:00000046
[ 2676.460000] [<c0025020>] (asm_do_IRQ+0x0/0x94) from [<c0027904>] (__irq_svc+0x44/0xe0)
[ 2676.460000] Exception stack(0xc2b83d28 to 0xc2b83d70)
[ 2676.460000] 3d20:                   00000001 bf0500f0 00000000 bf050118 bf04c524 00000001
[ 2676.460000] 3d40: bf04c524 00000000 c2b83dd2 c2b82000 40024000 c2b83d9c c2b83d70 c2b83d70
[ 2676.460000] 3d60: bf02b884 bf00e2a4 20000013 ffffffff
[ 2676.460000]  r6:00000040 r5:d102b000 r4:ffffffff
[ 2676.460000] [<bf02b818>] (_MAP_RegGetData+0x158/0x20c [cadrv]) from [<bf02bb0c>] (Page0_ReadREG+0x40/0x90 [cadrv])
[ 2676.460000]  r7:00000000 r6:00000005 r5:00000000 r4:c2b83dd2
[ 2676.460000] [<bf02bacc>] (Page0_ReadREG+0x0/0x90 [cadrv]) from [<bf029c64>] (K_BatteryGetCapacityOne+0x44/0x3e0 [cadrv])
[ 2676.460000] [<bf029c20>] (K_BatteryGetCapacityOne+0x0/0x3e0 [cadrv]) from [<bf02a300>] (K_BatteryGetCapacity+0x20/0x84 [cadrv])
[ 2676.460000]  r7:c337d3a0 r6:c2b83e78 r5:c2b83e17 r4:00000000
[ 2676.460000] [<bf02a2e0>] (K_BatteryGetCapacity+0x0/0x84 [cadrv]) from [<bf02a38c>] (K_BatteryStatus+0x28/0x78 [cadrv])
[ 2676.460000]  r5:c2b83e78 r4:beabac98
[ 2676.460000] [<bf02a364>] (K_BatteryStatus+0x0/0x78 [cadrv]) from [<bf007bd4>] (constructing_function_call+0x80/0x98 [cadrv])
[ 2676.460000]  r4:c2b83f00
[ 2676.460000] [<bf007b58>] (constructing_function_call+0x4/0x98 [cadrv]) from [<bf007c60>] (ioctl_entry+0x74/0x128 [cadrv])
[ 2676.460000]  r6:beabac10 r5:beabac10 r4:beabac1c
[ 2676.460000] [<bf007bec>] (ioctl_entry+0x0/0x128 [cadrv]) from [<bf007808>] (drv_ioctl+0x50/0x88 [cadrv])
[ 2676.460000] [<bf0077b8>] (drv_ioctl+0x0/0x88 [cadrv]) from [<c00d14c0>] (vfs_ioctl+0x90/0xa0)
[ 2676.460000]  r5:c0045306 r4:c337d3a0
[ 2676.460000] [<c00d1430>] (vfs_ioctl+0x0/0xa0) from [<c00d1728>] (do_vfs_ioctl+0x74/0x1ec)
[ 2676.460000]  r6:c0045306 r5:beabac10 r4:beabac10
[ 2676.460000] [<c00d16b4>] (do_vfs_ioctl+0x0/0x1ec) from [<c00d18e4>] (sys_ioctl+0x44/0x6c)
[ 2676.460000]  r4:0000000a
[ 2676.460000] [<c00d18a0>] (sys_ioctl+0x0/0x6c) from [<c0027d60>] (ret_fast_syscall+0x0/0x2c)

[ 2676.460000]  r7:00000036 r6:4056e214 r5:0000000a r4:000000bd

其實從這個LOG來看,最後是卡在UART的txReady上,而兩個行程都訪問到了差不多的點,最後的結論是在等txReady是個死結,要不是有工具就真的找到死,真的不誇張,從User space查到Linux Kernel module超長的路程。

http://www.ibm.com/developerworks/cn/linux/l-cn-sysrq/

2013年4月3日 星期三

22k 責任歸屬的省思


一家公司起薪3萬,拼一下跟那堆電子新貴的上班時數差不多,就有7萬,還年年調薪5%~8%,這麼好康,你知道那家公司還在缺工嗎?

彰化的正新輪胎以及建大就是這樣,我親戚的小孩跟他說有這種工作機會,他老媽就反對,為什麼?

給我的理由就是,辛苦阿~輪胎廠沒冷氣,還要忍受橡膠的味道,人阿~好逸惡勞,辛苦的工作誰想做?

沒付出點代價,嫌錢給的少,合理嗎?

以我來說,專科畢業了13年,專業在軟體、軔體上,年薪大概只值個百來萬左右,其實一路走來看過很多人沉下去,也看過有些人浮出檯面,而台灣在軔體方面還是缺工,大概缺三成沒填滿,這工作輕鬆嗎?

軔體苦阿!除了要寫code之外,要吞下去的規格數量也比純軟體還多,廠商三不五時,怕你太閒每季給你更新,所要研究的項目除了偏硬的規格之外,還有軟體設計的領域,軔體在越來越大的系統上,還需要純軟的能力輔助,後來Linux當道,除了軟體、軔體之外還得搞系統,這樣包山包海的能力才有這價值,一路上看苦而待不下去的大有人在,更多的是跟不上技術升級的腳步而淘汰。

剛開始的時候,我入門當助理工程師,薪水也差不多2Xk,第一次調薪,每月就+7K,你不要以為是什麼猛獸本質被發現了,只不過就是比別人多一點認真而已,專注的投資在專業上的技能,慢慢的發酵而已,我一開始投資在技能升級上的時間,每天平均約16Hr,這要持續四年才能有所小成,而我少看了點電視、小說及漫畫,專心一致的在武裝自己的實力罷了。

在這些年的過程中,我認識幾個MIS,學歷也比我高,卻為了4xxk的年薪在煩惱,我不禁要問,這年頭學歷能證明什麼?

我發現,遇到問題的態度才是分歧點!

在公司中,我業餘的多事,多管了台File Server,當初在架設時,MIS的論點是公司需要為了這機器找廠商買,我是覺得挑好的硬體,上個免費的作業系統Linux隨便搞都有,何必買?

在管理上,不只一次好心的提醒他,MIS會寫Script很重要,會因為好的系統讓日常工作簡化,很多事情自動化,他的論點是公司沒付那麼多錢,何必替自己找麻煩?(懶的寫,不想花腦經寫,最後遇到要用一定不會寫)

況且他認為誰做的誰要負責的,何必多事呢?

而我的論點是,有問題就修嘛,怕擔責任就虛度年華,何必呢?

所以他寧願處理每天使用者的雜事,手工去調閱檔案伺服器的紀錄,也不願意如我說的一樣寫些程式,讓系統自己管理,擠出來的時間可以好好的武裝自己。

各位可能對於MIS可以寫程式自動化的價值不清楚,我舉個例子來說,另外一個同事管理GPMS(Green Product Management System),他那官僚老闆要他做報表,畫個圓餅圖每週報告,好讓他家官老爺可以在會議上好好的表現一下,從剛開始幾十個產品料號納入管理,這圖做出來要了半天,到後來近百個料號,光畫個圖每週就搞了一天半,最後上線之後,那全部產品數百個產品料號要統計,那要花多少時間?

確定一周做的完?(官僚才不管這鳥事勒)

問題對某些人來說是麻煩,對我來說是金礦,以我這種賣腦力的人來說,老闆不就是花錢找人來解決問題的嗎?

寫個程式花了我一天,每次運作只大概幾秒鐘吧!

你覺得MIS會認真的想要解決這問題嗎?
這問題解的方法有沒有價值?
要我來說,從頭到尾,從資料庫撈資料,整理資料到寄電子郵件到老闆信箱,全部都嘛可以用排程自動做,你們公司的MIS有能力這麼解決問題嗎?(可以寄到那官老爺煩都不再燒我時間)

有些公司的IT部門被看不起,也不是沒原因的,學校訓練出來的學生,大多也沒真的具有解決問題的能力,系統跟系統間的縫隙,我看過一堆公司都是用「人工」填補,這個問題有兩個面向,一個是人員的素質不對,另外一個是管理者對IT價值的觀點是錯的,一個正面的公司,無論哪方面先跨一步往前都是好事,員工先跨出去,老闆能賞識一般不會虧待這份努力,萬一老闆沒水準不懂價值,功夫練完了,有了能力就準備飛走便是,反正良禽擇木而棲,而不是去虛耗時光、蹉跎光陰、渾渾噩噩的混日子。

對我來說,解決了問題的同時,也增加了本身腦力的價值,老闆根本也搶不走這個能力,他可以剝奪你的勞力產出結果,卻不能夠剝奪你的能力,如果覺得自己本身這價值被低估了點,能談的來則好,不然就是走人便是,工作不過就是替某人解決問題而已,有人想買能人出腦力,有人只想忠犬出勞力,看清楚想賣什麼就到想買什麼的哪間公司,而不是只是在抱怨。

很多MIS替老闆打工,卻只是叫老闆一直買軟體解決問題,而不是認真的替老闆解決問題,不然就是把IT搞成手工業,感覺做了很多事情,實質上也沒什麼功績可言,就雜事處理了一堆。

後來,剛好有同事去念所謂的二技,在那些日子裡,就一直向我討教畢業論文該怎麼做,過程中我發現幾個問題:


  • 某些教授對軟體偏愛有問題,台灣有些學校的IT教育很詭異,有些學校的教授根本就稱的上「某些軟體廠商的駐校業務員代表」,教學當中一直在強迫學生用某家的產品,或許是本身對這項軟體「用的」很專門,根本忘了軟體的操作教學是廠商的責任,不是要拿稅金去替廠商做教育訓練的吧,教育當局根本忘了大學教育的重點是什麼?
  • 畢業論文有兩種,一種是研究(問卷+統計),另一種是實作系統,後來實作系統的那堆人全部外包(統計其實也有人外包...),學校要指導教授以外的三位教授審核,比較負責任的教授乾脆直接問。
    • 教授:這是同學做的嗎?
    • 同學:...,是...外包做的。(這同學唯一的優點是~~誠實)
    • 教授:...,算了,那你們可以說明一下這是在做什麼嗎?
    • 同學:...,A嗯阿喔....,不知道
    • 教授:囧rz...
  • 比較負責任的教授,也比較硬,學生群起杯葛教授,然後被校長約談...為了學校生計,當這麼多,怎麼交貨呢?
  • 這二技畢業論文的水準比我們當時二專的專題還糟糕,小毛頭念了兩年做出來的東西跟,跑去多念了兩年也沒長進就算了,怎麼退步了呢?

你覺得這樣的品質印出來的文憑有什麼用途?

你覺得到業界,我們在面試的時候會怎麼看這些人?

有時候,我覺得22k要是請不到可以做事的人及能解決問題的人,就算便宜也是種浪費,老闆也不都是蠢蛋,蠢蛋不會也不應該讓你當老闆,有價值自然就會升值,沒價值貶值是正常的市場規則,在這種普遍不良的世道,凸出一點反而容易被看到。

如果真的在乎錢,很多高薪的工作仍然缺工,人不要為了好逸惡勞而找藉口賺不到什麼錢,也不要怕離鄉背井賺微薄的薪水,而寧願什麼都不嘗試的龜在家裡,更不需要為了老闆做事情,要為自己而做工作,武裝自己。

2013年3月29日 星期五

強力膠程式

基於俗話說:「正規表示式用的好,下班比較早。」的名言,又用了強力膠搞程式。

最近因為在搞NTP需要檢查輸入變數的IP或者是HOST NAME,需要用到正則表示式幫忙檢查。可是又不太想老老實實的寫程式,一心只想要早點下班,老實說,總歸一句話就是人懶。


sprintf(szCmd, "echo '%s' | grep -q '^\\(\\w\\+\\.\\)\\+\\w\\+$'", strIpHostName);
if(system(szCmd))       {ret=d_NTP_IPURL_INVALID_FORMAT; goto CNCS_EXIT;}


兩行寫完,就下班了~~~XD

這主要還是利用正則表示式幫忙檢查樣式,grep -q 會回應成功或失敗,要system會回0表示樣式對了,當然啦~用system是會比較慢一點,幸好這程式是不太在意效率問題,而我也剛好比較在乎下班時間,所以就這樣搞了。~~XD

原來的shell命令大概像下面這行一樣
echo "www.google.com.tw" | grep -q '^\(\w\+\.\)\+\w\+$'
執行成功或失敗,這樣看不太出來,加上後面那一段,格律對了,就顯示IP/HOST NAME OK
echo "www.google.com.tw" | grep -q '^\(\w\+\.\)\+\w\+$' && echo 'IP/HOST NAME OK'

搭一些牙籤上去讓C語言做出來的程式跑起來,可以運作就收工了,就看起來像是用強力膠黏出來的程式風格,也證明了俗話說的好。

PS.在GNU C上正途是用regcomp這函式,只是這樣程式寫起來就會落落長。。。

2013年3月28日 星期四

sed 與 awk

在script執行過程當中想要改東改西的這種搞法,被稱為串流編輯,而有這種能力的工具,被稱為串流編輯器(stream editer),這當中有兩個工具很好用,就是sed與awk。

這兩個工具在用之前,需要有正規表示式(Regular Expression)的知識,俗話說:「正規表示式用的好,下班就會早。」,它是用來描述字串共同的模式,利用樣式來描述字串的規則,再利用這規則來搜尋、修改等動作。

sed是一種非交談式的串流編輯器,可動態編輯資料,主要是比對樣式,符合就做指定動作。

awk是一種可以處理資料、產生格式化報表的語言。主要是拿來讀取檔案,逐列取出當成紀錄(record),每筆紀錄用欄位分隔符號切開,然後輸出每個欄位的值。

這兩種神兵,用的好,可以讓事情少很多,有些用手敲個老半天,手工打造的表格,用這兩個兵器搞下去,往往一行之內就搞定了。

參考wiki : http://zh.wikipedia.org/wiki/AWK
參考文件:http://www.delightpress.com.tw/bookRead/skns00004_read.pdf
參考網頁:http://linux.vbird.org/linux_basic/0330regularex.php

最近用awk的小心得

$find . -name '*.ko' | awk -F "/" '{printf("%s\t\t->\t\t",$NF)};{for(i=1; i <= NF-1; i++) printf("%s/",$i)};{printf("\r\n")}'

awk的$NF指的是最後一個欄位,這一段命令事先找到資料夾下的.ko檔案,把路徑及檔名丟給awk處理,先印出最後一個欄位,然後加上->符號隔開檔名,最後再用for迴圈組合路徑出來。

結果就是像大概下面這個表一樣。

w1_ds2431.ko -> ./target/lib/module/2.6.32.9/kernel/drivers/w1/slaves/
mmc_core.ko -> ./target/lib/module/2.6.32.9/kernel/drivers/mmc/core/
sdhci.ko -> ./target/lib/module/2.6.32.9/kernel/drivers/mmc/host/
sdhci-platform-bcm5892.ko -> ./target/lib/module/2.6.32.9/kernel/drivers/mmc/host/
sdhci-pltfm.ko -> ./target/lib/module/2.6.32.9/kernel/drivers/mmc/host/
mmc_test.ko -> ./target/lib/module/2.6.32.9/kernel/drivers/mmc/card/
mmc_block.ko -> ./target/lib/module/2.6.32.9/kernel/drivers/mmc/card/
scsi_wait_scan.ko -> ./target/lib/module/2.6.32.9/kernel/drivers/scsi/
做這個表,主要是把kernel module拷貝到rootfs當中,之前寫的script可以使用這個表列出來的檔案拷貝到rootfs當中,一個一個手工keyin製表,是很勤勞的人在做的事情,實在不符合我的風格,對~我就是個懶人,所以就用了awk把表搞出來,當然使用perl一樣做的到,只是剛好今天換了工具而已。

2013年2月21日 星期四

【轉】qt觸摸屏隱藏鼠標指針


方法1:運行加參數-nomouse

鼠標指針是沒了,觸摸屏也失效了。

方法2:QWidget::setCursor(QCursor(Qt::BlankCursor)

例:this->setCursor(Qt::BlankCurror);
只希望在某個QWidget(或QDialog等)控件上不出現鼠標指針。其他窗口仍會顯示鼠標指針。

方法3:main函數中調用QApplication::setOverrideCursor(Qt::BlankCurror);


方法4:main()函數加入 #include <QWSServer>,實例化QApplication後,添加QWSServer::setCursorVisible(false);


注意:方法2和3只有在動一下觸摸屏後鼠標才會消失,第4種在整個程序啟動到運行都不會出現鼠標指針。

終於去掉這討厭的鼠標了。

引用: http://www.myexception.cn/program/660869.html