2013年11月1日 星期五

CPU burst and IO burst

作業系統講到行程排班使用CPU
常提到行程一生使用資源會在CPU burst及IO burst交替之中度過。

那到底什麼是burst?
如果查burst原義,比較接近的大概是
http://www.merriam-webster.com/dictionary/burst
 a short period of producing or doing something that begins suddenly
也就是短期突發作某事。

引申用到CPU/IO burst就是指一段連續使用CPU/IO時間。
若硬要口語化翻譯,大概可考慮如下幾種譯法:

  連續CPU使用期連續IO使用期
  CPU連用期IO連用期
  CPU使用期IO使用期
  CPU期IO期

這和一般簡化為CPU時間或IO時間相較,意義上更為明確。

2013年10月18日 星期五

何謂類別及物件

一般對程式的認知,不外是利用一群指令,可對資料運算的工具。
傳統非物件程式語言視方法為程式結構主體,內含諸多指令,負責運算資料。
物件導向語言相對重視資料本身,視資料為主體,稱為物件
而和資料相關的運算,則附屬於資料,稱為物件方法。

可以想見不同類型的資料及運算可以包裝成不同物件,
每個物件皆有一個型別,稱為類別
類別可想成是物件的模版,一個類別可以產生無數物件。
類別定義了物件的長相及能力,分別稱為
1.狀態: 資料儲存處,又稱為欄位,屬性,或物件變數
 狀態本身也可以是另一個物件。
 狀態一般宣告為私密等級,不允許外界直接存取。
 若要讓外界存取,通常會提供公開存取方法,供統一管制窗口之用。
2.行為: 對狀態之運算,又稱為函數,訊息,或物件方法
 行為一般宣告為公開等級,允許接收外界傳來訊息,直接呼叫啟動。

舉例: 以Java API的掃瞄器java.util.Scanner物件為例,
   其狀態包含一可讀資料來源(Readable)物件,
   其行為則包含nextInt(), nextLine()等方法,
   允許外界從Readable物件取得一個整數,或一行字串。

物件可以視為類別的實體,故類別產生物件的過程,也稱為實體化
以程式觀點,實體化可以想像成配置一塊記憶體空間,供存放物件之用。
此空間的名稱即為物件名,此空間的型別即為類別名。

舉例: 如下兩指令可產生一個掃瞄器物件,並從鍵盤取得一整數,

   Scanner input = new Scanner(System.in);
   int n = input.nextInt();


其中,
new就是類別產生物件的實體化指令,後面要接類別建構方法,稱為建構子
建構子必須和類別同名,()一般會帶參數,供物件屬性填入初始值之用。
new Scanner(System.in)表示產生一塊型別為Scanner之物件空間。
其可讀資料來源設定為系統輸入流System.in,即鍵盤,
Scanner input = 表示將此物件名字取為input。

有了物件就可呼叫其物件方法,啟動所需行為,
input.nextInt()表示呼叫input物件的nextInt()方法,從鍵盤回傳一整數,
int n =表示將此整數存入另一變數n格子,供後續利用。

PS:中英對照
class 類別
object 物件
instance 實體,物件
attribute 屬性
state 狀態
behavior 行為
method 方法
function 函數
field 欄位
message 訊息
instantiation 實體化
instance variable 物件變數
instance method 物件方法
constructor 建構子

何謂變數

變數位於記憶體,目的在儲存資料,故可想成格子。
每個變數皆有如下屬性:
1.名稱: 供辨識不同格子。
2.型別: 決定格子可放資料種類。
3.大小: 格子儲存容量。
4.值:   格子放的資料內容。一次只能放一份,新的進來,舊的就不見。
5.位置: 格子所在的記憶體住址。位置一般由編譯器決定,程式無法控制。

舉例:
A.指令int x=3;代表有一個變數,名稱x,型別int,大小4B,值3。
B.指令String y="3";代表有一個變數,名稱y,型別String,大小2B,值"3"。

變數在正常使用之前,需經過如下初始化過程:
1.宣告: 告訴編譯器,變數的名稱,及型別
2.配置: 依宣告型別,從記憶體切出一塊合適空間,命名為變數名。
3.給初值: 為宣告變數設定初始值。

舉例:
A.指令int x;代表宣告變數x,配置型別為int格子,初值為0,
  指令x=3;代表格子內填入3。
  以上兩行指令也可合併成一行指令int x=3;代表宣告+配置+給初值一氣呵成。

B.指令Scanner input;代表宣告變數input,型別為Scanner,初值為null,
  指令input=new Scanner(System.in);代表配置型別為Scanner物件,
  其輸入流初值為System.in,取名為input。
  以上兩行指令也可合併成一行指令Scanner input = new Scanner(System.in);
  代表宣告+配置+給初值一氣呵成。

2013年7月5日 星期五

object transfer over Internet in Java

Here is a Client/Server connection sample for remote function calls in Java.
Map data structures are used to wrap parameters and results.
All serializable types are supported in function calls which include String, Vector, and ImageIcon.
Multithreading is used to allow multiple client requests simultaneously.


/*--------------------------------------------
$ java ClientMap4
connecting...
socketOut
socketIn
cmd:login1
writeObject(input:login1)
readObject()->output
output:LOGIN1
output1:user
output2:passwd
cmd:
*/
import java.util.concurrent.*;  // Executors
import java.util.*; // Vector
import java.net.*; // Socket, ServerSocket
import java.io.*; // InputStream,InputStreamReader,BufferedReader
   // OutputStream,PrintWriter
import javax.swing.ImageIcon;

public class ClientMap4
{
  final int defaultPort = 1234;

  static BufferedReader consoleIn;  // 控制台輸入流
  static PrintStream consoleOut;  // 控制台輸出流

  static Socket skt;
  static ObjectInputStream  socketIn;  // 連線插座輸入流
  static ObjectOutputStream socketOut;  // 連線插座輸出流

  @SuppressWarnings("unchecked")
  public static void main(String args[]) throws Exception
  {
    int port = 1234;

    if(args.length==1)    // 命令列有給埠號參數
      port = new Integer(args[0]).intValue(); // 則依命令列埠號

    consoleOut = System.err;
    consoleIn  = new BufferedReader(new InputStreamReader(System.in));
        consoleOut.printf("connecting...\n");

    skt = new Socket("localhost",port);

        consoleOut.printf("socketOut\n");
    OutputStream socketOs = skt.getOutputStream();
    socketOut = new ObjectOutputStream(socketOs);

        consoleOut.printf("socketIn\n");
    InputStream socketIs = skt.getInputStream();
    socketIn = new ObjectInputStream(socketIs);

    Map<String, Object> packetOut;
    Map<String, Object> packetIn;


    while(true)
    {
      String cmd,parm1="user",parm2="passwd";
      String output=null,output1=null,output2=null;

      // 測試字串陣列容器
      Vector<String> parm = new Vector<String>();
      parm.add(parm1);
      parm.add(parm2);

      // 測試結果集容器
      Vector<Vector<String>> vecResultSet = new Vector<Vector<String>>();
      Vector<String> record1 = new Vector<String>();
      record1.add("user_id_1");
      record1.add("passwod_1");
      record1.add("email_1");
      Vector<String> record2 = new Vector<String>();
      record2.add("user_id_2");
      record2.add("passwod_2");
      record2.add("email_2");
      vecResultSet.add(record1);
      vecResultSet.add(record2);

      // 測試圖片
      ImageIcon pic = new ImageIcon("test.jpg");

        consoleOut.printf("cmd:");
      cmd = consoleIn.readLine();
      packetOut = new HashMap<String, Object>();
      packetOut.put("cmd",cmd);
      packetOut.put("parm1",parm1);
      packetOut.put("parm2",parm2);
      packetOut.put("parm",parm);
      packetOut.put("vecResultSet",vecResultSet);
      packetOut.put("pic", pic);

        consoleOut.printf("writeObject(input:%s)\n",cmd);
      socketOut.writeObject(packetOut);
      socketOut.flush();

        consoleOut.printf("readObject()->output\n");
      packetIn = (Map<String, Object>) socketIn.readObject();
      output  = (String) packetIn.get("output");
      output1 = (String) packetIn.get("output1");
      output2 = (String) packetIn.get("output2");

        consoleOut.printf("output:%s\n",output);
        consoleOut.printf("output1:%s\n",output1);
        consoleOut.printf("output2:%s\n",output2);
    }
  }
}





/*--------------------------------------------------
$ java ServerMap4
ListenTask: thread:pool-1-thread-1 (9) waiting at port:1234
ServiceTask: thread: pool-1-thread-1 (9) serving /127.0.0.1:59626
ServiceTask: socketOut
ServiceTask: socketIn
ServiceTask: end of constructor
ListenTask: thread:pool-1-thread-1 (9) waiting at port:1234
        begin running
        waiting input
        cmd=<login1>
        parm1=<user>
        parm2=<passwd>
        parm=<[user, passwd]>
        vecResultSet=<[[user_id_1, passwod_1, email_1], [user_id_2, passwod_2, email_2]]>
        pic=width:728,height:90,write to 'test2.jpg'
        output=<LOGIN1>
        output1=<user>
        output2=<passwd>
        waiting input
*/
import java.util.concurrent.*;  // Executors
import java.util.*; // 用到 Vector
import java.net.*; // 用到 Socket, ServerSocket
import java.io.*; // 用到 InputStream,InputStreamReader,BufferedReader
   // OutputStream,PrintWriter
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.Graphics2D;

class ServiceTask implements Runnable
{
  BufferedReader consoleIn;  // 控制台輸入流
  PrintStream consoleOut;  // 控制台輸出流

  Socket skt;
  ObjectInputStream  socketIn;  // 連線插座輸入流
  ObjectOutputStream socketOut;  // 連線插座輸出流

  String host;
  String port;

  public ServiceTask(Socket skt) throws IOException
  {
    // 取得螢幕輸出流
    consoleOut = System.err;

    // 由連線插座,取得主機,埠號
    this.skt = skt;
    host = skt.getInetAddress().toString();
    port = String.valueOf(skt.getPort());
    consoleOut.printf("ServiceTask: thread: %s (%d) serving %s:%s\n",
     Thread.currentThread().getName(),
     Thread.currentThread().getId(), host,port);

    // 由連線插座,取得插座輸出入資料流
    consoleOut.printf("ServiceTask: socketOut\n");
    OutputStream socketOs = skt.getOutputStream();
    socketOut = new ObjectOutputStream(socketOs);

    consoleOut.printf("ServiceTask: socketIn\n");
    InputStream socketIs = skt.getInputStream();
    socketIn = new ObjectInputStream(socketIs);

    consoleOut.printf("ServiceTask: end of constructor\n");
  }

  @SuppressWarnings("unchecked")
  public void run()
  {
        consoleOut.printf("\tbegin running\n");

    Map<String, Object> packetOut;
    Map<String, Object> packetIn;

    // 測試字串陣列容器,結果集容器,圖片
    Vector<String> parm;
    Vector<Vector<String>> vecResultSet;
    ImageIcon pic;

    try
    {
      // 進行多次對話,直到輸出為QUIT為止
      while(true)
      {
        consoleOut.printf("\twaiting input\n");
        packetIn = (Map<String, Object>) socketIn.readObject();
        String cmd = (String) packetIn.get("cmd");
        String parm1 = (String) packetIn.get("parm1");
        String parm2 = (String) packetIn.get("parm2");
        parm = (Vector<String>) packetIn.get("parm");
        vecResultSet = (Vector<Vector<String>>)packetIn.get("vecResultSet");
        pic = (ImageIcon) packetIn.get("pic");

         consoleOut.printf("\tcmd=<%s>\n",cmd);
         consoleOut.printf("\tparm1=<%s>\n",parm1);
         consoleOut.printf("\tparm2=<%s>\n",parm2);
         consoleOut.printf("\tparm=<%s>\n",parm);
         consoleOut.printf("\tvecResultSet=<%s>\n",vecResultSet);
         consoleOut.printf("\tpic=width:%d,height:%d,write to '%s'\n",pic.getIconWidth(),pic.getIconHeight(),"test2.jpg");

         // save image for comparison
         Image img = pic.getImage();
         BufferedImage bi = new BufferedImage(img.getWidth(null),img.getHeight(null),BufferedImage.TYPE_INT_RGB);
         Graphics2D g2 = bi.createGraphics();
         g2.drawImage(img, 0, 0, null);
         g2.dispose();
         ImageIO.write(bi, "jpg", new File("test2.jpg"));

        String output = cmd.toUpperCase();
        String output1 = parm1;
        String output2 = parm2;
        packetOut = new HashMap<String, Object>();
        packetOut.put("output",output);
        packetOut.put("output1",output1);
        packetOut.put("output2",output2);
        socketOut.writeObject(packetOut);
        socketOut.flush();
         consoleOut.printf("\toutput=<%s>\n",output);
         consoleOut.printf("\toutput1=<%s>\n",output1);
         consoleOut.printf("\toutput2=<%s>\n",output2);

        if(cmd.equals("quit")) break; // 遇到quit指令結束
      }
    }
    catch(Exception e)
    {
      consoleOut.printf("ServiceTask: exception:%s\n",e);
    }
    finally
    {
      // 關閉插座資料流和插座本身
      try
      {
        socketIn.close();
        socketOut.close();
        skt.close();
      }
      catch(IOException e)
      {
       consoleOut.printf("ServiceTask: socket close error:%s\n",e);
      }
    }
  }
}

class ListenTask implements Runnable
{
  int listenPort;   // 監聽埠號
  ServerSocket listenSocket;  // 監聽插座
  PrintStream consoleOut;  // 控制台輸出流

  ExecutorService pool;  // 緒池

  public ListenTask(ExecutorService pool, int port) throws IOException
  {
    this.listenPort = port;
    this.pool = pool;

    consoleOut = System.err;

    // 建立監聽插座,可能丟例外
    listenSocket = new ServerSocket(listenPort);

    Runnable listenTask = this;
    Future f = pool.submit(listenTask);
  }

  // 監聽緒工作
  public void run()
  {
    Socket connectedSocket=null;

    try
    {
      while(true)
      {
        // 等待新連線
        consoleOut.printf("ListenTask: thread:%s (%d) waiting at port:%d\n",
         Thread.currentThread().getName(),
         Thread.currentThread().getId(),listenPort);

        connectedSocket = listenSocket.accept();

        // 啟動專屬緒,為新連線服務
        Runnable serviceTask = new ServiceTask(connectedSocket);
        pool.execute(serviceTask);
      }
    }
    catch(IOException e)
    {
     consoleOut.printf("ListenTask: accept raised IOException:%s\n",e);
      System.exit(0);
    }
  }
}

public class ServerMap4
{
  final int defaultPort = 1234;
  final ExecutorService pool;

  public ServerMap4(int port)
  {
    pool = Executors.newCachedThreadPool();  // 建立緒池
    //pool = Executors.newFixedThreadPool(10);

    try
    {
      if(port < 1024) port = defaultPort;
      ListenTask listenTask = new ListenTask(pool,port); // 開監聽緒
    }
    catch(IOException e)
    {
      System.err.printf("ServerMap4: %s\n", e);
    }
  }

  public static void main(String args[]) throws Exception
  {
    int port = -1;

    if(args.length==1)    // 命令列有給埠號參數
      port = new Integer(args[0]).intValue(); // 則依命令列埠號

    new ServerMap4(port);  // 啟動監聽及服務緒
  }
}

2013年3月27日 星期三

technician, associate, professional, expert, or architect


在網管領域的思科認證當中,一般分成如下五等級,


CCENT, Cisco Certified Entry Networking Technician,思科認證初級網路技術士
CCNA, Cisco Certified Network Associate, 思科認證網路技術佐
CCNP, Cisco Certified Network Professional, 思科認證網路技術員
CCIE, Cisco Certified Internetwork Expert, 思科認證連網專家
CCAr, Cisco Certified Architect, 思科認證設計師

其中,Associate(副,佐)因為不好翻譯,一般將CCNA譯為思科認證網路工程師,
結果名詞雖然易懂,但不易了解其級別地位之高低.
又Professional和Expert中文都翻成專家,也造成CCNP及CCIE不易以中文區別,
因此,參考一般公務體系的技術職等多分成士,佐,員三級,將之分配給三級認證,這樣就比較不會混淆.
這樣也產生一個簡單五級中英對照表,如下:

  士  technician
  佐  associate
  員  professional
  家  expert
  師  architect/master

可供中英互譯等級時之參考.
這其中,比較罕見的是professional譯成技術員,
但為了等級好分,及想將專家保留給expert關係,大致也還可以接受.

文獻:
1.交通事業人員任用條例,
  http://www.6law.idv.tw/6law/law/%E4%BA%A4%E9%80%9A%E4%BA%8B%E6%A5%AD%E4%BA%BA%E5%93%A1%E4%BB%BB%E7%94%A8%E6%A2%9D%E4%BE%8B.htm

  二、技術類;技術長、副技術長、高級技術員、技術員、技術佐、技術士。