2008-06-06

得到 Router 的 IP

如果拿到一台 router,可是卻不知道他的 ip,那要怎麼去 config 它呢?

有一個簡單的方法:

1. 先把自己的網卡設成 dhcp

2. 接到 router 的 LAN port

3. 用 ipconfig 檢查那張網卡的資訊

4. 看看它的 geteway,應該就是那台 router 的 ip。

close-on-exec

close-on-exec

【譯名】無

【說明】這是一個由 fcntl() 系統呼叫設定的旗標。由於子處理程序(child process)
會繼承父處理程序(parent process)的環境(environment)﹐在檔案

指標(file pointer)一併繼承的情況下﹐會造成彼此干擾對方讀取檔案的現象。為了改
正這個缺點﹐我們可以 fcntl() 的參數 F_GETFD 設定 close-on-exec 為 on ﹐這樣在
執 exec() 之後,此檔案描述詞所參考到的檔案會在 exec() 執行成功之後自動關閉。

http://proton.phys.tku.edu.tw/UNIX/Unix%20Dictionary/UNIX%20C.htm

不定變數

像 printf 這類的 function 是怎麼寫的呢?

int                             /* O - Number of bytes written */
my_Printf(const char  *message, /* I - Message string to use */
            ...)                /* I - Additional arguments as needed */
{
  int       bytes;              /* Number of bytes formatted */
  va_list   ap;                 /* Pointer to additional arguments */

  va_start(ap, message);
  printf("my printf() : ");
  bytes = vprintf(message, ap);
  va_end(ap);
  return bytes;
}

void main(){
    int i=5;
    my_Printf("my number : %d\n", i);
}

Bookmarks

Linux :

Linux Command Line Tips

Linux and USB 2.0

The Linux USB sub-system

Basic Linux kernel documentation

Linux 檔案刪除的回覆救援

Locale support in libc 5.4.x and higher

Linux Kernel v2.6

LinuxInsight

Linux defragmenting?  Yes , No

永遠的UNIX

Floppy Linux

Samba media

Linux-NTFS

BusyBox: The Swiss Army Knife of Embedded Linux

 

Network:

Beej's Guide to Network Programming

Windows Sockets

Study-Area

Java Script

 

Services:

GNU Wget

GMediaServer

iSCSI target

boa+auth+ssl 

超全的NFS文檔(FOR LINUX)

 

System:

USB tools

libiconv

uClibc

U-Boot

smartmontools Home Page

RAID-1, Part 1
RAID-1, Part 2

CUPS + SAMBA

20071111_象山行 200

http://www.cups.org/index.php

CUPS ( Common UNIX Printing System ),是在 linux上的列印工具。為了讓 user 可以把 NAS當 printer server,所以需要跟 samba 一起 build,讓 user 可以透過 samba 直接列印。下面列出幾點 CUPS 的需求:

1. driver 安裝

描述:
    driver 在client端安裝就好。

解法:
    在 samba config中加入 use client driver = yes 這一行。以下列出 samba 中所有 跟 cups 相關的設定:

        printcap name = cups
        load printers = yes

        printing = cups
        use client driver = yes
[ printers]
        comment = All Printers
        printable = yes
        browsable = yes
        public = yes
        path = /home/service/cups/log
        guest = yes

2. 權限問題

描述:
    在列印東西時,會跳出 "未發送 StartDocPrinter 呼叫" 的視窗。

解法:
    似乎是 samba config 中寫的 path 權限沒開,把所有CUPS folder 的權限都改成 777 (-rwxrwxrwx),就可以印了。

3. root 列印權限

描述:

    換成新版 CUPS 後無法列印,後來發現是 CUPS 中有以下這段:

if (!getuid())
{
     /*
      * Change to an unpriviledged user...
      */

      setgid(fileinfo.st_gid);
      setuid(fileinfo.st_uid);
}

    造成無法找到 usb  printer。

解法:
    把這段 mark 掉就好了。

4. Printer information

描述:
    希望在 smaba 中可以看到 printer 的廠牌型號等資訊。

解法:
    CUPS 在 build 的時候,在 $CUPS$/lib/cups/backend/ 會有一支usb 的程式,可以掃出插在 usb port 上 printer 的資訊。利用這資訊去 create cups printer,在samba 上就可以正確顯示。

5. Samba show

描述:
    希望可以插上 printer時才出現,沒插就不顯示。

解法:
    在 scheduling 中利用 usb 去檢查是否有 usb printer,若有插則加入 printer,沒插就把 printer 刪掉。注意要紀錄現在 printer的狀態,不然只要插著就會一直加入 printer。還有當列印的工作在進行中時,usb是無法偵測的,有可能是因為 device busy,所以在檢查是否有插 printer時也要檢查是否有列印的 process在運作中。

6. Spindown

描述:
    1. 雖然用 usb 可以得到 usb printer的 information,但它卻會使用到好幾支 lib,這些 lib 存在於硬碟中,每次呼叫都造成硬碟的讀取。也就使得 spindown 無法運作。

    2. CUPS 為了安全性問題,會每隔一段時間就產生新的認證檔,但因為認證檔會記錄於硬碟上,所以也會造成 spindown 失效。

解法:
    1. 每次開機都把usb 跟 lib copy 到 ramdisk 下,讓它不會直接用到硬碟。用到的 lib 有以下三隻:

        libcrypto.so.0.9.7
        libcups.so.2
        libssl.so.0.9.7

    2. 在 cups.conf 中設定為0,表示只有開啟的時候才做一次。

        RootCertDuration 0

7. CUPS spool

描述:
    在列印的時候,Windows會先把檔案傳送到 NAS,而 CUPS會將他存在 spool中,等檔案傳送完成再傳送給指定的 device。但當檔案過大,有可能會造成 spool所在的partiotion空間不足。

解法:
    原本spool是在 system partition中,所以當檔案稍大就會空間不足,在 cups.conf 中指定 spool 的位置到 user partition,就比較不會有 size 的問題。寫法如下:

    RequestRoot /config/Disk/Disk1/cups-spool

8. DNS issue

描述:
    如果指定的 DNS 是連不到的,在啟動cups跟 smaba時會等到 timeout 才繼續啟動,造成開關的動作非常廢時。

解法:
    在 /etc/hosts 中記錄 localhost,如下:

    127.0.0.1       NAS NAS.WORKGROUP localhost

iTunes Server

http://www.mobile01.com/topicdetail.php?f=300&t=147903&cache=0

http://www.fireflymediaserver.org/

mt-daapd (firefly)是個不錯且知名的iTunes server。只要指定 share folder 就可以直接利用 iTunes 聽歌了。加上他有一些簡單的設定,還蠻好用的。下面列出一些遇到的問題:

1. scan interval

描述:
    希望可以隔一段時間就自動重新掃描歌單。

解法:
    在 mt-daapd.conf 加入 rescan_interval 即可。

2. default share folder

描述:
    如果server沒有指定到正確的 folder,就會無法開啟。

解法:
    default 設成 share,如果原本的 folder被刪除,則自動指向 disk1 的 share。

3. ID3 語系

描述:
    因為 ID3 有不同的語系,所以在 iTunes client上看起來會有亂碼。 iTunes client固定使用UTF-8編碼,因此當分享出來的ID3 tag編碼不正確則會出現亂碼。

解法:

1. 讓user自己去將編碼做轉換的動作,只要利用iTumes將歌曲的ID3 tag version轉換掉,再轉回來,就會是UTF-8的編碼了。

2. 將 iconv整合進 mt-daapd中,並在config中多一項設定指定 character set,所有的ID3 tag 將會從指定的charset 轉換成 UTF-8。

UPnP

http://www.intel.com/cd/ids/developer/asmo-na/eng/downloads/upnp/overview/index.htm

http://ushare.geexbox.org/

在我們的 NAS 中UPnP server是用 Microsoft 開發的 ushare。ushare 是針對 xbox所開發的 UPnP server。最新版的還支援了 PS3,是套免費且堪用的server。ushare在porting方面的問題不大,反而是在跟不同的 UPnP client溝通時會有問題。在製作時遇到以下問題:

1. Windows Authorization

描述:
    UPnP在溝通時是利用 http在傳輸資料,而使用 xml 來定義他的各種行為。而ushare在建立聯結的過程中,有去跟 client做驗證,因為當初他的設計是為了搭配 xbox,所以也要求要通過 Windows的認證。由於一開始驗證都是以WinDVD 8為 client,OS 使用的是 Windows XP,所以 Windows 驗證方面也沒有問題。直到拿來跟別台 DMA做測試時才發現不能撥放,因為一般的 DMA並沒有包含 Windows的認證,那連線也就建不起來了。

解法:
    ushare 所送出的 xml是 hard code的。所以找到他定義各項 service的部份,並將其中微軟驗證的部份拿掉,如此一來即可不需驗證。可以參考GeeXboX uShare

 

2. XBox 360 & PS3

描述:
    照第一項的作法在這兩台機器上無法正常使用。

解法:
    最新版的 ushare有支援,因此抓下來重 build即可。唯一的問題是如果不照第一項的方式修改,其他各家的 DMA 可能無法使用,但若照其方法修改 XBOX則無法使用,可能是他要求要驗證的關係吧。最後是因為說 XBOX 比較多人用,所以不去更改。

在解第一項問題時,花了一些時間去抓封包,比較封包差異,研究無法撥放的原因。在做NAS時,很常感覺到一有問題就說要抓封包,有的情況下確實很有用,抓到封包比對後可以看出 code哪裡可能會有問題,但也常常不知道抓來要做啥,這之間的矛盾很難取捨。

GPIO

GPIO,通用型之輸入輸出(General Purpose I/O)的簡稱,功能類似8051的P0—P3,其接腳可以供使用者由程式控制自由使用,PIN腳依現實考量可作為通用輸入(GPI)或通用輸出(GPO)或通用輸入與輸出(GPIO),如當clk generator, chip select等。

在 NAS 有幾個功能需要靠設定或讀取GPIO來完成:
1. system initial (LED config, usb power on, etc.)
2. LED blinking
3. reset
4. shutdown
5. usb copy

其實設定 GPIO 就是去設定某個 register,當值改變後就硬體的行為就會跟著改變。在hareware spec 中會詳細定義哪個 register是可以設定,以及哪些 bit是 Input,哪些是Output,Input 是指只能讀取,Output是指可以設定。而在 bootcode跟 kernel中要跟據hardware spec 去設定好bit的屬性。

可以把 GPIO的運作看作是開關,如果設成 1 就表示通路,設成 0 就表示斷路。

Firmware Upgrade

在開發 embedded system 產品時,幾乎是一定會需要 firmware upgrade,NAS當然也不例外。
NAS的 upgrade 包含了幾個部份:
1. bootcode
2. kernel
3. root filesystem
4. config
5. remote package (services)

由於 embedded system 上的資料主要是以 flash 來儲存,在開機時,MTD driver 會將flash 上的位置 mapping 到 MTD device,這樣接下來要讀寫 flash 就可以直接透過 MTDdevice。下面是 mapping 的訊息:

Creating 4 MTD partitions on "phys_mapped_flash":
0x00000000-0x00180000 : "kernel"
0x00180000-0x00320000 : "squashfs"
0x00320000-0x00380000 : "jffs2"
0x00380000-0x00400000 : "boot"

有一點要注意的是,要把資料寫入 flash前,一定要先用 flash erase 將其清空,否則會無法寫入。而寫入的方法可以像操作一般檔案一樣,直接用 open/fopen 開啟後操作。

Clock Cycle Counting

#include <time.h>
clock_t clock(void);
用來取得 process所佔用CPU 的大約時間

http://csapp.cs.cmu.edu/public/ics/code/perf/clock.c

clock_t clock( void );. 這個函數返回從「開啟這個程序進程」到「程序中調用
clock()函數」時之間的CPU時鍾計時單元(clock tick)數

start = clock();

end = clock();

cpuTimeUsed = ((double) (end - start)); // get cpu clock time

Sleep Less Then 1 Second in C/C++

sleep(int second);

usleep(int micro-second);

 

{

struct timeval *tv;

    tv.tv_sec = 0;          // sec
    tv.tv_usec = 30;        // micro-second

}

select(1, NULL, NULL, NULL, timeout);  

GeeXboX uShare

A free UPnP A/V & DLNA Media Server for Linux
這是 Microsoft 為了 xbox 所開發的 upnp A/V server
在他的 description 中做了三件事:
1. msr
2. cds
3. cms
裡面只有 2 跟 3 是必須的,1 是微軟要做一些驗證,如果是對一般的 DMA (八成是用linux)就會失敗,原因不名,是抓封包的結果,也懶的去找了。要讓其他 client 都可以用,只要把他的 description xml  中 msr 那個 service 整段拿掉就可以了。

但如此一來,就無法跟XBox系列產品做溝通,修改之前還是要依個人需求而訂。

Building and Porting Code

Building code

x86 :
    # ./configure
    # make
    # make install

arm :
    # ./configure --prefix=/path/to/service/home/ --host=armeb-linux \
                  --target=armeb-linux
    # make
    # make install

 

Porting code

      一般來說,porting code 要利用 cross-compiler 的技術,但並非所有的 source 都支援 cross-compiler ,這一點要注意。

    在 building/porting code 時,最重要的大概就是 configure file 及 Makefile file,現在大部份的程式都是利用軟體去產生的,詳情請看: Makefile介紹

    有了 configure and Makefile 就可以來 porting 了。

    首先,可以用 ./configure --help 檢視有哪些選項可供使用。在 cross-compiler 時,--host、--target 是必須的,而 prefix 則是告訴 configure 要把 service 的 root 設定在哪裡。用 --help 檢視到的,是這個 service 本身所提供的 option,可能某些 option 會需要配合某些 library,那就要去 download 這些 library 來 build,或是看 tool-chain中有沒有提供這個 library 可以使用。

    如果是比較小的程式,可能只要指定好 --host and --target 就可以了。但通常是不會那麼順利的 Orz。先試過用上面的方面 build 過,如果不行,就要看錯誤是出在哪裡。下面列出已經有遇過的問題,提供參考:

1. cross compiler 沒有指定好:

    目前我使用的是 armeb-linux-gcc,所以必需要先把他加入環境中,否則找不到對的compiler 一定是 build 不起來的。

2. 沒指定正確的 build tool:

    例如 ar, strip 都是常使用到的 tool,如果沒指定對的,就會有問題。指定的方法可以在 ./configure 前面先設定。如下:

    CC=armeb-linux-gcc AR=armeb-linux-ar STRIP=armeb-linux-strip ./configure

當然,這些 tool 都要在環境中先設定完成才可以用。

3. cannot check SOMETHING when cross compiling:

    這就比較麻煩,因為當 configure 發現是 cross compiler 時就不給做下去了。這時先看看 ./configure --help 中有沒有可以讓他跳過不要 check 的選項,如果發現這個選項是一定要的,那就只能去改 configure 了:

    # vi ./configure

找到那一行,應該可以發現他如果無法檢查就會跑 { (exit 1); exit 1; }; }。把他全都拿掉,並把它檢查的值設定好:

// mark these to allow cross compiling
- line 31537:
{ { echo "$as_me:$LINENO: error: cannot check SOMETHING when cross compiling" >&5

- line 31538:

     echo "$as_me: error: cannot check SOMETHING when cross compiling" >&2;}

- line 31539:   { (exit 1); exit 1; }; }

+ line 31540:   ac_cv_func_SOMETHING_void=no

關於最後一個 ac_cv_func_SOMETHING_void 要設成 yes 或 no 是不一定的,要看前後文來決定,不過如果真的不知道,就先設成 no 吧(看看會不會有問題再說)。其實也可以在configure之前先 export 就好了:

# export ac_cv_func_SOMETHING_void=no
# ./configure

4. 缺 library:

    這是很常見卻又很麻煩的問題。首先當然是看看 tool clain 中有沒有提供缺少的 library,如果有就簡單了,只要把它選起來 re-build 就可以了。

# cd /path/to/tool-chain/build-root/
# make menuconfig

 

Timeout Effect

在寫程式時常會設定所謂的 timeout 時間,但若 timeout時間的比較是與系統時間做比較,則要特別注意系統時間是否會被改變,如果有被改變的機會,則可能造成程式錯誤。

Enhance CTorrent 有時無法下載的原因是因為裡面有比較時間的部份,上次在 datastore 中也遇到類似的問題,下次再遇到程式不明原因無法執行,或執行結果有問題, 或許可以看看是否有所謂的 side effect.

在 embedded system上可以先看看當時的時間是否正確。
(就是用 time() 會抓到的時間)

The Difference between squashfs and jffs2

根據 Roger 的說法
------------------

squashfs : 存在 flash 上,當要使用到某部份時,再將"那部份"解到 ram 上

jffs2 : 存在 flash 上,開機時將所有東西解到 ram  上

Linux Driver

 

result=register_chrdev(iGpio_Major, DEVICE_NAME, &gpio_fops);

iGpio_Major : major number of device node

DEVICE_NAME : device name (/dev/DEVICE_NAME)

gpio_fops : address of structure of driver functions

ex.

static struct file_operations gpio_fops =
{
    .owner      = THIS_MODULE,
    .read       =   gpio_read,
    .write      =   gpio_write,
    .open       =   gpio_open,
    .release    =   gpio_release,
};

addr=ioremap(GPP_DATA_OUT_REG,4);

ioremap : mapping device to virtual memory for read/write

GPP_DATA_OUT_REG : physical address of device

addr : virtual memory address of device

result = unregister_chrdev(iGpio_Major, DEVICE_NAME);

Big Endian & Little Endian

 

所謂的 big endian 與 little endian 是指 CPU 處理資訊時位元排列順序的不同, 若 big 是 10101010,則  little 會是 01010101。但,CPU 真正在處理時看到的又會是如何呢 ? 是把所有的位元都倒過來放?還是照 instruction size 來做顛倒的動作?是 32 bits processor 就每 32 bits 倒一次,64 bits processor 就每 64 bits 倒一次嗎?真正運作的方法究竟是哪一個?

答案是,都不是!!

真正運作的方式是要看 processor 處理 bits swap 的定義,以 Marvell 5182 (64-bits) 為例,在 user manual 中有說到 bits swap 的運作方式是 :

Swap Mode:

    The DMA supports swapping, for descriptors only, for both receive and

transmit ports, on every access to memory space.

0 : No swapping

1 : Byte swap : In every 64-bit word of the descriptor, the byte order is

    swapped such that byte 0 is placed in byte 7, byte 7 is placed in byte 0,

    byte 1 is placed in byte 6, byte 6 is placed in byte 1, byte 2 is placed

    in byte 5, etc.

    由此可見,它的交換機制是 byte swap,也就是以 byte 為單位做倒置。但 byte 與 byte 之間的順序性卻不會被改變。

2008-06-05

process 強制執行的方法

有時會想要讓自己寫的程式不被中斷,就可以這樣用。

#include <signal.h>

int main(){

    signal(SIGTERM,SIG_IGN);
    signal(SIGHUP,SIG_IGN);
    ...

}

在 signal(int signum, int handler) 中 指定 handler = SIG_IGN 表示忽略signum 所代表的 signal

SAMBA DNS Error

samba是linux上用來跟windows做分享的一種protocol(CIFS),詳情見samba網站

Please pay attention to the error messages you receive. If any error message reports that your server is being unfriendly, you should first check that your IP name resolution is correctly set up. Make sure your /etc/resolv.conf file points to name servers that really do exist.

Also, if you do not have DNS server access for name resolution, please check that the settings for your smb.conf file results in dns proxy = no. The best way to check this is with testparm smb.conf.

--
samba 開啟太慢 -- Make sure /etc/resolv.conf correct!!

[BBS 舊文] hub, switch, router

 

作者  clytc (走吧!!!!)                                     看板  P_clytc
標題  [筆記] hub, switch, router
時間  Wed Jan 31 15:28:21 2007
───────────────────────────────

router : layer 3

switch : layer 2 or layer 3 (management)

hub : layer 1

--------------------------------------------------

router 通常具有 dhcp 等功能,適用於架設內部區網

--------------------------------------------------

switch vs hub

   switch 依照 port to mac 的方式傳送資訊,hub 利用 broadcast 的方式傳送 。因此 switch 會比 hub 有更低的 loading, 對網路上而言,就是產生碰撞的機會比較小

[BBS 舊文] Why I Prefer Procedural/Relational Over OOP

原文網址

以下是翻譯:

為什麼我使用程序導向,而不用物件導向

我的文章,大部份主題都是以打倒OOP為主,為因應大眾的要求 (或者是反彈,以你們的觀點來說),我在此詳細說明為什麼我使用程序導向,而不用物件導向的理由,主要的目的在於用p/r 取代 OOP。本文為一個大致的整理與說明,在此不舉特定的例子。個別的說明可參考散布於文章各處的超連結。

我們常說OOP將資料與行為作了整合,而其競爭對手 "循序性的程式設計法則 " 的方式,則是將他們分開處理。整合是好的、對的嗎?整合資料與行為是一件好事、還是壞事?如果我們觀察在這個世界上的其它事物,我們可以發現 "整合" 這件事情有時候只是一種 "優缺點的相互取捨"而已。"整合"有時候只是把東西弄得更複雜、更難以用相容性的東西來抽換而已。它把東西弄得更難單獨的分析。就像是吃擔子麵,你只是想吃魚丸,它卻老是與麵條糊在一起,然後事情就變得很麻煩。

老天爺將人類的腦袋分成兩個部份。一部份負責邏輯,而另一部份負責情感。(這樣說也許過於簡化,卻符合大部份的狀況),如此基於"思維型態的區分" 一定是有它的道理所在,否則上帝應該將它們 "整合" 成一部份而不是分成兩個部份。同樣的,美國人將政府部門分成三個部份:立法、司法、行政。有的人立法、有的人詮釋法律、有的人履行法律(如果他們守法的話)。因此,在這邊已經有了兩個 "本來就應該分開" 的例子。

在我的觀點,P/R 程式設計法則,將資料與行為區分成兩個部份,一定也有其設計上的優點。它提供了一個資料與資料使用者(應用程式)間分明的性質界面。雖然為了配合此性質界面,必須付出一些義務及代價,但這些代價確是值得付出的。

P/R 程式設計法則,也就只有這麼一個性質界面,也是唯一的代價。如果你遵循這個法則,到最後你會發現,跟其它的法則比起來,其實它的效益才是最大的。這個法則的限制條件並不是隨意訂下的,而是經過周密的思維而得,我的看法,它是目前世界最了不起的軟體工具技術。與GUI一樣,它是少數令人讚嘆的技術,它是讓軟體科技向前進步的基礎。

這種界面的契約就好像是現代的高速公路系統。如果大家都願意繳稅,也願意遵守交通規則,在這樣的前題下,政府就可以據以建構龐大的高速公路網,讓我們可以方便、快速的從甲地到達乙地,而我們要做的,就只是要擁有一部車。如果你不同意這樣的作法,那麼你去鄉下住住看,在馬路不多交通不便的環境下,你的想法應該會改變才是。

這P/R 程式設計原則,簡單的來說就是:"如果你將資料放在一個特定的 Struct 中,那你將可以完完全全的操控它"。代數的發明者E. Codd 讓世界見識到數學的強大力量,它將一些複雜的彼此具相關性的數字化為簡單的代數方程式,或關連性的參數。

我們可以用一個簡單的代數方程式來表示一個 "模式",這樣省時又省力。這就好像我們可以用一些預先定義好的口令來命令人數眾多的軍隊一樣,而不用對軍隊中的每個人一一解釋說明。只要一次對全體發一次口令即可,不管是對十個人或者是十億個人發號施令,命令都會被忠實的執行,這跟下達公文指示是一樣的意思。還有一種方式是將命令編碼到一個結構中再傳送,OOP多多少少會用到這種方式,在這邊我們看到OOP還是用了 "老方法",而不是一成不變的用 "比較現代" 的方式(據它們說比較不過時)。OOP本質上它的作法是,一次只命令一個士兵,一個接著一個。

不只是代數方程式可以裝載一堆具關連性質的參數,也可以將這一堆參數放在一張各欄位定義清楚的表單上(當然你須先具備相應的表單流覽器)。至少就我來看,將資料放在表單之中比將資料放在程式中來的簡單而有彈性。相對於放到表單上,將資料放在程式碼中比較難以閱讀、搜尋、交叉比對以及過濾。當然不太可能將所有的資料通通都放在表單之中(至少在目今的技術/工具來看),但是在一些實際的例子中,你還是可以將大部分的資料放在裡面。

請注意!在我見聞所謂正式的關連性法則之前,表單就已經是我偏好的方式。(關連性技術並不是我大學時所學到的課程之一) 例如,在早期我習於將參數放在程式碼中時,程式碼就像以下這個樣子:

w = foo(norf,   "exmpl", 05,    g,  nork)
  x = foo(glob,   "zorg",  33,    r,  frot)
  y = foo(zonnof, "blag",  22.5,  z,  melo)
  z = foo(fli,    "pag",   13.1,  k,  pendmend)

 

它顯示了我個人對參數運用方式的一時想法或偏好,而忽略了我後來自己一再耳提面命對於關連性法則的要求。我不知道同樣的參數,如果同時有別人來應用,它將呈現如何的風貌。我收到有人寄給我的E-mail,提到他在這些參數上碰到麻煩,它們不知道這些參數所代表的意義。我的觀察是:每個人都有不同的思維模式,包含程式設計師也一樣,彼此想法的差異性都很大。

因此,把表單與資料關連性(方程式)分開的法則,已比程式本身還重要(至少我認為),你越是把的資料放在表格中,你就越能夠去編輯、管理、改變對資料的應用方式。資料庫本身也變得更精確、有力。程式碼也就變得不用那麼講究了。

OOP法則比較像是 GOF Patterns,以程式碼為中心。傾向將這個世界上所有簡單的、複雜的資料通通都整合到程式碼裡面。而P/R的作法,資料雖然由代數方程式控制操作著,但資料本身存在程式碼以外。因此若只是要修改這些代數方程式,就變得很相對容易,比修改程式加資料整合的結構方便多了。由於只涉及代數方程式與程式間的整合,關係相對單純,意味著當要修改程式碼中的代數方程式時,所牽連的範圍比較小,不會有動一髮牽全身,搞成滿臉豆花的夢喭。

將資料與程式分開的另一好處,就是可以輕易地,讓不同的程式語言來處理同樣資料庫。Java、FORTRAN、Smalltalk和LISP 可以共用相同的 "名稱模塊" (即Structure),那是因為 "名稱模塊" 是放在於資料庫中而不是放在程式語言中。相反的,想要讓不同的程式語言,如COBOL、Visual Basic和 Java,來分享其創造的 "物件" 則幾乎是一件不可能辦到的事。

 

方程式的其它功能


方程式不只是數值關係的表現而已,還有用於判斷分發的規則也是。例如,循序型的程式碼有以下的型式:

task X {
    ....
    if [expression_A] {
       [perform something 1]
    }
    if [expression_B] {
       [perform something 2]
    }
    ....
  } // end task X

 

如果需要修改條件A下的分發方程式,就只要修改方程式的部份,其它的部份都不需要動到,這樣一來,程式的變動的幅度少之又少。

OOP意圖將行為程序附掛在結構或所謂類別成員上,像是聖誕樹樹梢上的裝飾燈炮一樣。分發程序因此就成了一種綁在樹稍分支上或數幹網路上的實質物體。基於某些理由,OOP迷似乎很喜歡這種作法。但是就我的觀察,這樣的作法其實並沒有讓程式變得比較友善、易於了解。因為分發程序總是需要一再的修改,在這種情況下,如果分發程序又牽連到其它的物件分發程序成員,那就會變得很麻煩。

因此,我比較喜歡直接引用代數關係式,而不喜歡將它們放在物件結構中(請注意OOP的作法是將代數關係式放到物件結構中),我發現直接對付代數關係式比將它們放到物件結構中來處理來得方便且可靠。這個直接的觸感,讓你切實感受了代數關係式的存在,好處就像我剛剛所提的。這直接引用代數關係式的作法是非常好用的,至少對我來說。

演化歷程的分岐P/R 和 OOP 對於 "成員管理",有著不同的歷史演化路徑。在早期Structure 剛剛誕生的時候,在C裡面它叫作Struct,在 Pascal 中它叫 Record,在Cobol 中,它叫 Data definitions,在使用打孔卡片的時代,它叫打孔卡片的Layout。

隨著程式越來越龐大,Structure 也開始變得越來越複雜。對於如何處理複雜的結構,出現了兩種不同的流派。OOP 是其中一種流派的極致表現;Database則是另外一種截然不同的流派。OOP的目的在讓程式語言能夠輕鬆的管理這些複雜的結構。

然而,Database走向的人,意識到可以用一般且通用性的方式來運用這些結構。他們運用各種方式而開發出 "通用性的結構管理"(資料管理)的工具,並分析資料庫的使用模式,因而定義出若干用於資料庫操作的固定指令,從此以後,Database的操作,就開始超乎於任何特定的應用目標、應用程式或程式語言之外。

我認為第二種方法是比較好的(至少對於客製化的商業軟體來說)。當OOP還在試圖讓應用程式能夠更方便的運用資料時,第二種方法已經早就不需要在這個議題上傷腦筋,並且它的運用方法也已經非常簡單。OOP為了讓資料庫的應用更為簡便,常常需要對資料庫作大量的重構的工作,但是第二種方法根本就不需要作這些額外的工作。當OOP提供了你九十九種工具來讓你打造自己的機車時,第二種方法早就給你了功能完備且已可駛出家門的汽車。

好了,在我分析了這些好處之後,也來說一說它的缺點吧!我不是說它完全沒有缺點,但是它的確是沒有什麼大的缺點。如果真的有問題發生了,還是有許多現成的工具及技術可供應用的。同時到目前為止,我還沒有碰過什麼問題,大到需要將整個專案翻過來,重新規劃的案例。

OOP提暢者最常提到的好處就是,只要切換物件,行為就隨之直接切換。OOP提暢者宣稱 "抽象化的資料來源及型式",因此可以讓使用者可以不必過慮於資料詳細型式及它的實作方式。但是我沒有看過任何實際的例子,因為使用了這種OO作法而增加了什麼重大的效益的。例如,許多場合,有些資料須要定期更新,如果是OO的作法,就是需要定期呼叫一個成員函式來重寫資料(這個資料庫還可能需要先重構),如果我想要看資料的內容是什麼,或者是想要啟動資料的更新作業,則還要去實作並呼叫Views 和 triggers成員函式來達成功能,這真是 "脫了褲子放屁==多此一舉。

那些聲稱 OOP "保護" 或 "包裹" 資料以避免或減少存取點數量,而這些存取點它們必須被追蹤或改善。他們以為,資料庫往往是廣為開放或完全裸露在外的。然而,如果它們在他們的程式碼內,重構資料庫操作函式,則它們還是製造了
相同的問題,資料庫還是為特定程式打開著。這個複雜的問題牽涉到了複雜的好壞取捨的問題。每個人都會有不同的觀點。

在那些吹捧OOP的文獻中,所描述的資料庫的缺點,其實大部份都是虛構及誇大不實的。我作了一個結論,在我的看法,直接引用資料庫方式所提供的彈性、動態、模組化等優點,遠遠超過其產生的小小缺點。沒有必要因噎廢食,想想這一個道路哲學:為了顧及到那個也許會走到的碎石子路,所以全部的人應該都要買吉普車,來應付那可能的萬分之一的機會,而犧牲了馳騁於高速公路上的性能。

有些OOP暢議者說,將OOP與RDBMS搭配在一起,雙方皆可獲得世上最大的效益。然而,我看到卻的是它們彼此衝突又重覆彼此工作的狀況。GOF模式本身就像是一個舊約聖經,一個不去好好運用資料庫的功能,卻要自己用複雜的程式碼,一個個來處理手工索引的程式,怎麼行的通。也許GOF模式是用在資料庫不存在的地方,但這似乎是不太可能的事。許多OO迷,甚至是大部份,傾向使用一種OOP資料庫(OODBMS)或者完全不使用資料庫。然而,OODBMS現在在商業應用上已經是一個失敗的產品,它已無法成為RDBMS之外的另一種替代方案。甚至有人認為OOP資料庫的觀念本就與OOP的法則本身天生就是相互矛盾的。因此,不用說也知道,OOP之於資料庫已經開始過時,前途黯淡。

在此聲明我可沒有說關連性技術與表單可以完全取代GOF或類似GOF的模式。是有一些類似的功能可以在P/R下實現,但大部份還是要靠資料庫或掌控資料庫的工具來完成。

OOP的擁護者又有分化成兩種不同陣營的傾向(有些是在中間)。第一種為 "分類學者",他們緊抱著簡單的事物分化原則,事物一旦被分化成一種類別,便與其它的類別完全互斥,而此種類別可以再度分化成彼此互斥的次類別,這即是類別繼承觀念的基礎。這卻是令我常批評它的地方,它們用太過於單一的觀點來描述真實世界的事物,這使得它在應付這些事物的變化時顯得招架不住。這是因為同一件事物,往往有許多不同的面向及觀點,互斥類別樹表示的只是其中之一的可能性。

以關連性為思維中心的觀點來看,類別樹只是Structure 眾多面貌中的其中一個可能。有可能是堆疊、樹狀、簇列…等,就看當時的需求是什麼。同樣的一筆資料有可能同時屬於堆疊、樹狀或者是簇列中的一部份。這樣的Structure對關連性的思維來說,它是可以隨意組織的。但是如果用一個死板板硬梆梆的來類別分化法來處理它,並放到程式碼中,將失去了或減少處理該資料的其它面向的能力。加上,為什麼有些資料要靠程式碼才可看得到而有些又需要經由資料查詢工具?這真是讓我感到矛盾。

 

第二種陣營,我叫它 "浪漫的理想者"。我想連它們自己應該都會同意,對於客戶的實際需求,簡單的繼承範例,在實務上都是起不了什麼作用的。

 

更不幸的,這些浪漫的理想者基本上都只是在製造複雜化的問題。這個所謂OO新玩意,在碰到實際的資料庫問題時,就不得不失去了只用簡單繼承就可以完成程式碼的理想。它們需要重新創造資料管理系統,要讓類別再去橫向整合其它的類別,一下左邊的類別,一下右邊的類別,一下上面的類別,一下下面的類別,這樣才可取得所需要的資料面向。P/R 的應用法則,就比它高明多了,在程式碼內沒有所謂的資料,而是用索引或索引鍵,你至少不用對每筆記錄都要準備一個引用索引或索引鍵,如果使用Class的方式來處理,兩百筆資料就要兩百個Class的處理動作

某些OO迷將會指出關連性的方法只能適用在資料庫面向的轉換,而不適用在演算法。然而至少在我所處的領域裡,絕大部分事物都是性質參數的集合,或者是可以輕易將其轉換成性質參數的集合的。我曾經作過將程式碼放在資料參數中的嘗試,藉以減低我對不同資料處理方式的差異性,但事實上,我老是感到這麼作是不必要或者是沒有用的。

個人以為,SQL不是一個理想的查詢語言,但是比起OOP的方法,它還是進步許多。OO迷有時常抱怨,與資料庫的連結點重覆太多次,寫起來太費力。事實跟可以不用這麼作,只有標準或傳統的方式才需要這麼作,設計準則本身並不這麼要求,所有一般性的連結點可以技巧性的定義成一個點,SQL 評論網頁對此有更詳細的說明。

我非常喜歡利用資料庫工具,來對所有的資料庫作交叉關連分析的工作,有不少專門的工具在作這些事,可以對數噸的資料作管理的工作。OOP的作法,是將資料直接從資料庫裡全部倒出來再處理,這樣程式內的緩衝區內就會像爆炸案現場一樣的亂成一堆,看起來真是可怕。我幾乎不想用這種方式來管理大量的資料,所以同樣的,我也不會想用這樣的程式碼來從事我的工作。

 

每當我想整理非樹狀結構的OOP程式碼,Class 的關連圖畫到最後,都會畫不下去。一大堆關連指向線,密密麻麻分布在整張紙上。如果是使用P/R的方式,通常不需要這麼作,至少在條理清晰的程式碼上是如此的(不幸的OOP,大部分都不需要)。如果會有需要,大部份的情況都是:在IF 或 While 條件式後方出現了goto 指令,這是一種很老舊的程式寫作習慣,現在幾乎都不用了,但看到OOP,又不禁讓我想起那個時代。當我使用OOP的時候,我老是要Key-in database 的參照到所有的Class中,這樣才可對那些資料作排序、過濾、搜尋等等的工作。如果是使用P/R的作。如果是使用P/R的方式,這些工作早就已經在資料庫工具中完善地作好了。不管是要看資料庫的概廓,還是要從事查詢。設計程式時,不管是需要那一種資料庫的查詢功能,或者是它們之間的任何組合,只要用IDE來整合就可以了,你都不需要自己來寫相關的程式碼來實現功能。

以下還有許多文章,它們對關連性資料技術有更詳細的說明,就我的觀點,它們對於那些需要處理複雜關連性的資料是有用的。如果處理對象是可以將轉換成關連資料庫的,則越是有關連性需要管理,則越是容易。

P/R設計法則的真正力量不在於程式語言本身,而在關連性的模式及思維方式。當P/R設計法則,將系統設計的複雜部份,逐漸從程式語言中抽離的時候;OOP則在程式語言上動腦筋,試圖以加強程式語言功能的方式來達到目的,結果只是把事情弄得越來越複雜。依據P/R設計法則,程式形成了簡單易讀、容易維護的面貌。它還沒有到死的時候,相反的,它已輕易找到了它自己的定位,即所謂否極泰來。

-全文完-

[BBS 舊文] BEA 研討會

作者  clytc (走吧!!!!)                                     看板  P_clytc
標題  BEA 研討會整理
時間  Wed Aug 18 11:03:40 2004
───────────────────────────────

BEA dev2dev 研討會  2004 / 8 / 17
==================

1. 目標是以 SOA (Service Oriented Architecture)為導向。

2. 一個成功的技術人員要具備以下三直種條件 :

    1. 要磨練自己的技術,但不要太過執著於技術。現在要走的是 SOA ,而不是TOA (Technique Oriented Architecture)。
    2. 格局要放大。要看到的不只是眼前的 project。
    3. 判斷開發工具的能力。每種 project 都有適合自己的開發工具,而身為一個 IT員,我們必需要能在遇到不同的 project 時,找出一個最適合開發此 project 的工具。

3. 終極目標 : Liquid Computing

[BBS 舊文] 想像中的公司

這是當初在心機幫論壇上發表的,現在回頭看看,就跟yahoo或露天拍賣很像,是讓各家商店進駐用的。只是2004年的時候,拍賣這東西還沒有這麼流行。

作者  clytc (走吧!!!!)                                  看板  P_clytc
標題  小火星公司..
時間  Mon May 17 18:14:37 2004
───────────────────────────────

現在幾乎家家戶戶都有電腦,相信以後一定每個人每天都離不開電腦。可是每個人總是會有購物的需求,在要吃東西或買東西的時候就要打斷你的工作或遊戲,實在是很機車的一件事。如果有個網站,我稱為"商業電子化公司",如果這家公司可以讓你不用離開電腦也能得到你想要的東西,那不是很棒嗎?

我在想,這家公司所做的是一種線上購物軟體平台,我們不需要賣給使用者(不怕被盜版),可以賣給各個商家(例如pizza店、家具店),並讓使用者可以自行從想要的商店下載那個商店的購物清單,甚至可以幫他搜尋他想要的東西有哪些店有在賣,如此一來,使用者就不需要去記錄各家的網址或電話。只需連上網,然後在桌面上點一下就可以訂購你想要的東西。

而這家公司的工作則是去跟各商店接洽,並說服他們買我們的軟體,說不定還可以因此而順便幫他們寫資料庫等周邊配套,聽起來還不錯吧。再者,我們也可以在這家公司的網站上放置我們有做的商店的軟體(plugin),供人下載。這樣一來,對使用者而言,他們可以不用到處去尋找所需商店的網址,也還是可以得到那商店的軟體。對公司而言,可以因為很多人來抓東西而得到其他廣告商的資助,對客戶而言,等於公司可以免費幫他們打廣告。

而這個軟體則必須提供幾個功能..
1. user-friendly 介面
2. 網路連線傳輸資訊
3. 商店資訊更新
4. 列印訂購收據或其他資料(option)
5. 其他

---2004/05/15-13:36:24 - 61.30.68.*---

♂ naa
聽起來不錯 但是有很多問題
第一個 今天你是使用者 當你想買吃的東西時 就去網路上訂購
但是你要確定每一家商店都有電腦 而且他們還可能要僱用一個專門的人來即時更新
否則定一個披薩要等30分鐘以上
都有可能

第二個
今天若是友人想買一些大東西 或是價格比較昂貴的 就心理上來說 看的到才安心 他們可
能還是得實際去看實品
一但他們出了家門 就不是你的客戶了
第3個 另外就是你這種比較類似電子商務的東西 賣的東西容易被限制 今天如果你在電腦
前想買一瓶飲料 照你的想法看來當然不錯 但是有哪一家店會為了一瓶飲料幫你外送???

其實可能還是有很多問題還是需要考慮一下 因為你要做的好像是跟"電話"比方便 若是比
不贏 就很難變主流

---2004/05/15-14:36:36 - 218.167.15.*---

♂ 小火星
對於第一個問題...
當我們幫一家商店寫軟體時..當然他們要先有足夠的硬體..

如果一家店連所需的硬體都沒有.. 那這交易當然是不會成交..
而且他們也不需要有專人來看...
就跟我們用電話訂是一樣的.. 可能當電腦收到訂單時..
就發出個通知的聲音.. 那麼店裡的人自然應該去處理..

第二個問題...
就如同現在很多線上購物(如etmall). 我們當然只能傳送圖片.. 可是對於user而言. 他們
可能可以先逛逛線上百貨.. 等覺得哪些可以買時.. 在把清單列印出來.. 然後去百貨公司
看實物..

第三點..
有誰會只為了買一瓶飲料而出門買東西嗎..
在台灣還有可能.. 但是在國外的話.. 為了一瓶飲料開車去買東西.. 你花掉的汽油可能比
那瓶飲料還多..
再說.. 如果一家店是不提供外送服務的話.. 那自然也就不會使用此系統了...

我想也是還有問題啦..因為沒有很仔細的去評沽...
不過覺得網路越來越發達... 透過網路取得資訊似乎是未來的驅勢了..才會有這種想法..
跟電話比起來的話..
不需要去記電話號碼可能是比較大的優勢吧...
而且透過網路.. 透過這軟體.. 也可以將最新的折扣直接傳送到每個人的手中.. 而不用打
電話過去才問..

 

---2004/05/15-15:01:45 - 61.30.68.*---

♂ B
小火星呀
我突然想到ㄌ一ㄍ問題耶
尼覺ㄉ每ㄍ公司都會需要那種軟體ㄇ
我絕ㄉ,那要先看那ㄍ公司電子商務化ㄉ程度而定ㄅ
假設什ㄇ都真滴可以用網路下單滴話
如果客人下單ㄉ東西
不符合一間公司他外送ㄉ經濟效益ㄉ話
它會去用尼這套軟體ㄇ

♂ 小火星
這問題我也想過..
可是只要真的有符合user的需求.. 那就夠啦..
說不定user會因為懶的出門而選擇了有提供此項服務的公司..
那其他公司就有可能會因為注意到這個問題而也來找我們做阿...
所以這一點還好啦.. 重點是這東西要真的合user的口味阿..
那一家公司願不願意提孕~送服務就不是我們能決定的了..
不過我想只要通用的話.. 他們想不提供外送也不行了吧.
這是商業上的趨勢...

 

再不然.. 他們也可以提出多少錢以上免運費的服務..
降就可以解決成本的問題了...

---2004/05/16-02:47:47 - 61.30.68.*---
--
目前... 還只是個想法..

[BBS 舊文] 實習感想

因為無名要關了,所以把以前的文章貼出來保留。

作者  clytc (29外加12... 好辛苦)                    看板  P_clytc
標題  心態.....
時間  Wed Sep 17 17:50:38 2003
───────────────────────────────

回想實習,我所得到的並不是程式的寫法,也不是電腦組裝技術,更不是人際間的互動,而是讓我了解了現在社會工作的狀況。不是打工,而是一位資工的學生要如何工作。也讓我了解了資工出身該會的東西、會面對到的問題,以及在社會上的競爭力,這次實習改變了我的心態。

上學期,我讀書只是為了讀書而讀書,沒有任何的目的,只是因為讀的開心,讀的快樂而讀。其實也是因為二下發生了一些事,讓我不再想到處去玩,不再想跟大家鬧在一起。過了一個暑假,現在讀書不再是因為高興而讀,因為我發現,讀書讀的快樂固然重要,但當你沒那心情時,書,也就不再會去讀了。所以現在的我,是為了未來而讀書、是為了競爭而讀書、是為了得到我所想要的能力而讀書。因此,我不再拘泥於學分,我不再受限於朋友,有人一起讀當然是好,但當沒有人陪時,我也不該為了他們而停下腳步。我已經停太久了,再等待只會害了自己。

所以,當沒有人一起努力時,自己就該努力求生,在未來的日子中,還有很多很多的困難要面對。如果只一昧的依賴別人,當沒人可依賴時,我想可能會無法承受吧。

現在想想,當我自己一個人在國外時,有誰會陪你一起修課?又有誰會為了你而停下腳步咧?所以我必須要培養起自我學習的能力,我才有可能獨當一面。

 

 

技術導向

目標就像遠方的山,看起來很遙遠,但只要往前行,總有到達的一天。

用來紀錄我的學習狀況,一方面可以瞭解自己做的東西,另一方面也可以做為複習。

人總是健忘的,過了一陣子就忘了之前做的東西,曾經遇到的問題,就必須要再重一做過一遍,然後再重新忘記,就這樣不斷的循環,不僅沒有效率,也浪費了很多時間。希望可以把經歷過的整理起來,也可以訓練自己整理資料的能力。

2008-06-04

Jason Tech

★★★★★★ 傑森系列 ★★★★★★