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

2012年8月1日 星期三

INTEL HEX 格式

Intel HEX是一個文字檔,用來用來紀錄相對應的二進制碼。

格式:
:llaaaatt[dd...]cc
||||||||||||||||`` CHECKSUM (Zero checksum)
|||||||||```````- DATA
|||||||``- TYPE
|||||||     `- 00 : data record
|||||||     `- 01 : end of file record
|||||||     `- 02 : expended segment address record
|||||||     `- 04 : expended linear address record
|||````- ADDRESS
|``- LENGTH
`-START - colon

範例:

:10010000214601360121470136007EFE09D2190140
:100110002146017EB7C20001FF5F16002148011988
:10012000194E79234623965778239EDA3F01B2CAA7
:100130003F0156702B5E712B722B732146013421C7
:00000001FF



  Start code
  Byte count
  Address
  Record type
  Data
  Checksum




參考資料:
http://en.wikipedia.org/wiki/Intel_HEX
http://www.keil.com/support/docs/1584/

2012年7月26日 星期四

再論Linux開機

從電腦上電到出現命令提示符號間,系統經過了許多血汗的努力,這過程在使用者角度上不太重要,但,如果想要定做一個小型的Linux系統,就需要了解Linux整個啟動的過程。

當電腦上電之後首先是執行BIOS的程式,接著由BIOS交接到磁碟機上的MBR,通常OS Loader會載到MBR,這Loader負責把OS 核心(Kernel)與rootfs檔案initrd.img載入到記憶體中,並把控制權交接給核心運作,之後會解開initrd.img到記憶體上,成為暫時的rootfs但是是在RAM上,被稱為initrd (INITial Ram Disk),解開的rootfs之中有init這檔案,核心會去執行它,init(or linuxrc)必須要可以執行,可以是Script,有人稱它為Application Manager,這程式接手之後就得負責把磁碟機驅動起來,之後要掛載檔案系統,建立一些必要的設備節點,最後是根目錄切換,切換之後再去執行新的目錄中的init,把完整的系統驅動起來。

  1. bootloader載入kernel及initrd
  2. kernel解開initrd,並釋放initrd所佔用的記憶體空間
  3. 將rootfs掛載到ram disk上
  4. 執行 init (initialization)
  5. 掛載真正的rootfs
  6. chroot執行/sbin/init
所以第一次掛載ramfs時候如果需要開機到RAID上,就需要修改initrd.img這檔案,驅動起RAID並且掛載上再切換到RAID上,或是需要掛載iSCSI的磁碟當成系統碟也是需要修改它,如果不夠了解整個開機過程,相信沒辦法做到這一點,如果不需要太多的程序來搶資源,也可以讓自己寫的程式去領PID 1來用,整個系統就幾乎是你的程式獨占資源,所以對這些程序流程理解的愈深,相對的擁有的自由度就愈高。

當我在做小型的Linux系統的時候,我只需要開機到ramfs,所以不再往下交到目標磁碟機手上,而是直接用ramfs就好,一般這種作法搞出來的嵌入式系統是整個運作在記憶體上,好處是掛掉隨便使用者亂關都沒事,反正下一次要用還是得重新載入到記憶體上,只要原始的檔案沒毀損就沒事,缺點就是要等載入跟解壓縮,如此一來開機時間就會拉長,在很多的網通設備、多媒體播放器上都是這樣搞,只是他們也得面臨到開機速度的挑戰,所以就會看到各家奇奇怪怪的加速手段。

 在kernel版本2.6之後,initrd改用cpio製作,可以稱做cpio-initrd,它不需要特殊的block device或loop back device,製作過程比較簡單,而2.6與2.4的差異可以參考這一篇文章寫的。

上頭說的流程是Kernel 2.6以後的版本,而對於開機流程相信查到的文件常常是叫你去改inittab這檔案,如果你跟我一樣是用ubuntu/Debian就會發現事情並不單純(李組長語調),傳統的作法繼承於Unix-Like底下System-V init的作法,但是之後因為一堆隨身碟、硬碟、、、等隨插即用的東西出現,這個系統變得不太能夠適應,新的需求對於軟硬體的啟動、停止、掛載、移除,需要服務可以動態的啟動,傳統的sysVinit是基於runlevel的系統,使用runlevel(單、多使用者以及其它level)和鏈接(於/dec/rc?.d目錄,分別鏈接到/etc/init.d的init script)來啟動和關閉服務,而Ubuntu使用的是UPStart-Init則是基於事件的系統,它使用事件來啟動和關閉系統服務,傳統的SysVinit還有一個缺點,就是啟動需要跑一堆shell script,好處是很容易改,但是缺點是「慢」,這個缺點是從MacOS學到的教訓,在相同的位置上Solaris使用SMF(Service Management Facility),而Mac OS則使用Launchd,而Ubuntu則是傾向集這些軟體的優點於一身。

使用上也真的比較快,開機真的快多了,而且對於裝置服務的反應以比較靈敏,新的CPIO省去一次載入核心的時間,而init省去shell script運作產生的浪費,目前最耗時間的還是載入rootfs的時間(壓縮比加到頂也沒小多少,但是就明顯感覺核心解壓縮有點燒到點時間)。

sysVinit
  • initScript /rc script
  • rc => run commands
  • /etc/rc.d/init.d
  • /etc/inittab
    • id:5:initdefault:
  • /etc/rc.d/rc5.d
    • exp:
    • /etc/rc.d/rc5.d/K36mysqld
    • link to ../init.d/mysqld
    • K36mysqld
      • K : Kill/Start
      • 36: boot sequence
      • mysqld: service name
  • runlevel設定相互獨立
UPStart
  • event-driven/-based
  • 理順服務依賴關係以便實現平行啟動
  • 按需求啟動
  • Upstart job script
  • 有關UPStart相關的說明可以參考這一篇文章
也就是init最後不要交到真的磁碟機的/sbin/init而是交到ramfs裏面的/sbin/init,如果是用UPStart的服務,則是要搬相對的資料給他用,/etc/init目錄下的東西,底下的東西是.conf只是設定檔而已,不是shell script,而也要順便拷貝/etc/init.d目錄下的東西,除此之外還有相對應的設定檔也要拷貝,比如說ssh,除了init或init.d之外,還放了一個/etc/ssh/的目錄,也要順便拷貝走,與DNS相關的是/etc/hosts、/etc/resolv.conf、/etc/nsswitch.conf這3個設定檔,與帳號、密碼相關的設定檔是/etc/passwd、/etc/shadow、/etc/group這3個,如果說認証上有問題要注意/etc/pam.d/,PAM(Pluggable Authentication Modules),要順便注意/etc/nologin、/etc/securetty、/etc/security/*這堆。