2014年8月7日 星期四

何謂常數

Java允許程式中有常數存在,通常用來運算或令值給變數.
常數顧名思義就是一個不會變動的值.
常數也有型別,常見的常數型別如下:

1.物件類: 就只有空物件常數null

2.布林類: 就只有真假兩常數true,false

3.數字類: 分成整數及浮點兩類,
3A.整數類: 凡是沒有小數點的數字一律當成int型別
                若想視為long型別,可在整數後加L.
3B.浮點類: 凡是有小數點的數字一律當成double型別
                若想視為float型別,可在浮點後加F.
                10的多少次方可用E後面加數字表示.

4.文字類: 分成字元及字串兩類,
4A.字元類: 凡是單引號夾的字元,一律當成char型別
4B.字串類: 凡是雙引號夾的字串,一律當成String型別

舉例:
  Scanner sc = null;   // 令sc值為空物件null
  boolean b=false;   // 令b值為boolean常數假
  int i = 0;      // 令i值為int常數0
  long l = 0L;    //  令l值為long常數0
  double d = 1.23e2;  // 令d值為double常數1.23*10^2,即實數123
  float f = 0.0F;   // 令f值為float常數0
  char c = 'A';    // 令c值為char常數A
  char c2 = '好';  // 令c2值為char常數好
  char c3 = '\u000d';  // 令c3值為char常數Unicode字碼\u000d,即換行字元\n
  String s = null;  // 令s值為空物件null,字串也屬物件,故可填入空物件值
  String s2 = "";  // 令s2值為String常數空字串
  String s3 = "今天天氣很好\n";  // 令s3值為String常數今天天氣很好\n

數字類常數在令值給變數時,
若遇常數值放不進變數型別範圍,或大範圍型別放入小範圍型別,
則會出現error: possible loss of precision可能丟失精準度錯誤,
這時要使用強制轉型指令,常數前加(欲轉型型別名),才能編譯過關.

舉例:
   double d = 3;    // int小範圍型別放入double大範圍型別,沒問題
   float f = 3;   // int小範圍型別放入float大範圍型別,沒問題
   long l = 3;  // int小範圍型別放入long大範圍型別,沒問題
   int i = 3;  // int型別放入int同型別,沒問題
   short s = 3;  // int大範圍型別放入short小範圍型別,本有問題,但值3本身放得進short,故無問題
   byte b = 3;  // int大範圍型別放入byte小範圍型別,本有問題,但值3本身放得進byte,故無問題
   double d2 = 3.0;  // double型別放入double同型別,沒問題
 float f2 = 3.0;  // 有丟失精準度錯誤, 3.0常數視為double型別,不能放入較小範圍float型別內
   float f2 = (float) 3.0;  // double強制轉型為float,再令值就沒問題
   int i2 = 3.0;  // 有丟失精準度錯誤, 3.0常數視為double型別,不能放入較小範圍int型別內
   int i3 = (int) 3.0;  // double強制轉型為int,再令值就沒問題

PS
1. 數字類型別範圍,由小到大,如下: (可參考課本附錄D基本型別介紹)
       byte: 8bits: -2^7=-128 ~ 127=2^7-1
       short: 16bits: -2^15=-32768 ~ 32767=2^15-1
       int: 32bits: -2^31=-2e9 ~ 2e9=2^31-1
       long: 64bits: -2^63=-9e18 ~ 9e18=2^63-1
       float: 32bits: -3.4e38 ~ -1.4e-45, 0, 1.4e-45 ~ 3.4e38
       double: 64bits: -1.7e308 ~ -4.9e-324, 0, 4.9e-324 ~ 1.7e308

2. 中英對照
常數   constant, literal
單引號  single quote
雙引號  double quote
強制轉型 type casting

簡單if區塊

指令是程式最基本組成單元,其特徵是每道指令必有一個分號 ; 作結束,
因此,要數程式有幾道指令,最簡單方法就是數有幾個分號。
指令中最簡單就屬空指令,即單獨一個分號,前面不寫任何東西。
程式若遇空指令則不作事,直接跳到下一道指令執行。

又許多指令可以合併成一個區塊,其特徵是每個區塊必有一組大括號 {} 包夾起來。
區塊內可以放置眾多指令,供依序執行之用。
最簡單的區塊不外乎空區塊,內含0個指令,其作用和空指令相當,不作事。
次簡單的區塊則為單指令區塊,只含一個指令。
語法上,單指令區塊,其包夾之大括號皆可省略,
但初學者宜留著大括號,以方便區塊結構之辨識。

一個區塊的地位等同於一道指令,凡可以放置指令的地方都可以放置區塊
因此,區塊內除了放置指令,也可以放置區塊,形成多層區塊包夾情形。

程式正常是一道一道指令循序執行,若將每道指令視為單指令區塊,
則程式也可看成是一個一個區塊循序執行
如果在循序執行過程,希望有某區塊能依情況略過不執行
這時簡單if區塊就可以派上用場,其結構如下,

if(條件)
{
   // 此處放置條件成立情況下想執行之區塊指令
}

其中,if區塊最前面的條件可決定該區塊要不要執行,有點像流程轉向控制開關。
條件可放置任何能算出真或假值的邏輯運算式
若條件得到真,則區塊會進入執行;
若得到假,則略過區塊,跳到下一指令或區塊執行。

舉例: 假設scanner為初始化之掃瞄器物件。

int x;

x=scanner.nextInt();  // cin >> x;

if(x>5)
{
  System.out.printf("x:%d > 5\n", x);  // cout << "x:" << x << ">5" << endl;
}

System.out.printf("x:%d\n", x); // cout << "x:" << x << endl;

以上程式碼以區塊觀點共分成4區塊,
第1區塊宣告配置整數變數x指令,
第2區塊為x由掃瞄器物件給初值指令,
第3區塊為if區塊,含列印x>5指令,
但區塊執不執行由條件x>5為真否決定,
第4區塊為列印x值指令。

循序執行4區塊結果,於第2區塊接收x值後,
若x值大於5,則x>5條件成立,會進入第3的if區塊印x>5;
若x值小於等於5,則x>5條件不成立,會略過第3的if區塊不印x>5;
但不管印不印x>5,最後都會到第4區塊印x值。

可見簡單if區塊的用途適合在選擇性決定要不要多作事的情況。
選擇的依據就是區塊前的給定條件,多作事的內容則記錄在區塊內。

至於為何稱為簡單if區塊結構?
理由是以後還有完整if區塊結構,除了原來成立要執行的if區塊,
還有不成立要執行的else區塊,算是簡單if區塊的擴充完整版。


PS: 中英對照
分號  semicolon
大括號 brace
指令 statement
區塊 block
空指令  null statement
空區塊  null block
包夾 enclose
條件 condition
邏輯運算式 logical expression
循序執行 sequential execution
單指令區塊 single-statement block
簡單if區塊 simple if-block
完整if區塊 complete if-block
結構  construct,structure

數字系統轉換學習順序

2,8,10,16進位的正整數之間如何轉換,
建議依如下順序作練習:

0.10轉2: 練習8位元0~255十進位數字,利用成份法轉換成2進位數字.

1.10轉2,8,16: 以10進位數字為中心,利用長除法轉換成其他2,8,16進位數字,
2.2,8,16轉10: 將其他2,8,16進位數字,利用次方法還原成10進位數字.

3.2轉8,16: 將2進位數字用快速分組法轉換成8,16進位數字.
4.8,16轉2: 將8,16進位數字用快速攤開法轉換成2進位數字.

5.8轉16: 將8進位數字用攤開+分組法轉換成16進位數字
6.16轉8: 將16進位數字用攤開+分組法轉換成8進位數字

註: 算出任何結果皆宜反向驗證,確認還原數字相同否.
0.8位元2進位成份法:
    挑選適當128,64,32,16,8,4,2,1共8位元加回原來10進位數字.
    挑中位元其位置為1;未挑中位元其位置為0

1.長除法: 可將10進位數字轉換成n進位數字
    不斷利用除以n動作,留下餘數,直到原數除到商為0,
    依序將先留餘數放在最低數元,最後餘數在最高數元.   

2.次方法: 可將n進位數字,還原成10位位數字
    將n進位最低數元乘上n零次方,加上次低數元乘上n一次方,
    加上次次低數元乘上n二次方,以此類推直到最高數元用完為止.

3.分組法: 2轉8,由低數元開始,每3數元一組,改寫成8進位數元
          2轉16,由低數元開始,每4數元一組,改寫成16進位數元

4.攤開法: 8轉2,由低數元開始,每數元攤開成3個2進位數元
          16轉2,由低數元開始,每數元攤開成4個2進位數元

5.任一個數字的低數元比較靠近右,高數元比較靠近左.
  高數元: more significant radix
  低數元: less significant radix
  最低數元: 以整數來說,就是位在最右邊的個位數元

6.其他參考資料:
  https://ilms.csu.edu.tw/sys/read_attach.php?id=264201‎
  http://content.edu.tw/vocation/control/tp_nh/control/tp_nh/logic/ch2/p5.htm
  http://www.ltivs.ilc.edu.tw/kocp/logic/ch2/2-2.htm

數字系統轉換: 10進位篇

在了解數字系統之前,先了解何謂數字。一個數字通常由很多數元組成,正確的講,是從左到右依序寫在高到低位置上的多個數元組成。至於數字有那些數元可用則和數字是幾進位的數字有關,例如常用10進位數字有0~910個數元可用,16進位數字有0~9A-F16個數元可用,2進位數字則只有0,1兩個數元可用。其規則為b進位數字將有0~b-1b個數元可用。習慣上,將所有b進位數字形成的集合稱為b進位數字系統基數b數字系統,記作()b。一般數字若不作()b標記,預設為10進位數字
 
由於每個數字皆可用不同基數的數字系統表示,如何讓數字在不同數字系統之間轉換遂成為一個困擾。以下將先介紹次方法公式,適用於b進位轉10進位情況。
(an-1…a2a1a0)b= an-1bn-1 + … + a2b2 + a1b1 + a0b0
其中,(an-1…a2a1a0)b表示某b進位數字,包含n個數元,數元由高到低位置分別為an-1a0
1: 此公式之正確性可由10進位數字皆可依如下公式還原,而得到驗證。
(4567)10 = 4103 + 5102 + 6101 + 7100 = 4000 + 500 + 60 + 7 = 4567
2: 如下8進位數字為何10進位數字
(4567)8 = (?)10
 = 483 + 582 + 681 + 780 = 4512 + 564 + 68 + 71= 2423 = (2423) 10
3: 如下16進位數字為何10進位數字
(4567)16 = (?)10
= 4163 + 5162 + 6161 + 7160 = 44096 + 5256 + 616 + 71
= 17767 = (17767) 10
4: 如下2進位數字為何10進位數字
(1011)2 = (?)10
= 123 + 022 + 121 + 120 = 18 + 04+ 12 + 11 = 11 = (11)10
 
接下來介紹長除法公式,適用於10進位轉b進位之反方向情況。假設10進位數字x想轉為b進位數字(an-1…a2a1a0)b,則各數元a計算法如下。
x ÷ b = x0 = (an-1…a2a1)b   a0
x0 ÷ b = x1= (an-1…a2)b   a1
xn-2 ÷ b = xn-1= 0 … an-1
其中,先求得餘數放在低數元,後求得餘數放在高數元,直到商變0為止。
4: 同樣此公式之正確性可由10進位數字皆可依如下公式還原,而得到驗證。
    4567 ÷ 10 = 456 … 7
    456 ÷ 10 = 45 … 6
    45 ÷ 10 = 4 … 5
    4 ÷ 10 = 0 … 4
故得4567 = (4567)10
其實若將4567想成4103 + 5102 + 6101 + 7100=(((0+4)10+5)10+6)10+7就可理解為何長除法求得餘數要先放低數元位置,再逐一放到高數元位置原因。
 
2: 如下10進位數字為何8進位數字
(2423)10 = (?)8
    2423 ÷ 8 = 302 … 7
    302  ÷ 8 = 37 … 6
    37   ÷ 8 = 4 … 5
    4    ÷ 8 = 0 … 4
故得(2423)10 = (4567)8
 
3: 如下10進位數字為何16進位數字
(17767)10 = (?)16
    17767 ÷ 16 = 1110 … 7
    1110  ÷ 16 = 69 … 6
    69    ÷ 16 = 4 … 5
    4     ÷ 16 = 0 … 4
故得(17767)10 = (4567)16
 
4: 如下10進位數字為何2進位數字
(11)10 = (?)2
    11 ÷ 2 = 5 … 1
    5  ÷ 2 = 2 … 1
    2  ÷ 2 = 1 … 0
    1  ÷ 2 = 0 … 1
故得(11)10 = (1011)2
 
以上介紹了b10的次方法及10b的長除法後,理論上任何兩數字系統皆可經由10進位數字系統而作轉換。例如:816可先810,再1016即得。
 
PS:中英對照
數字 number
數元 radix
數字系統 number system
基數 base
quotient
餘數 remainder
高數元位置 more significant radix position
低數元位置 less significant radix position
2進位 binary
8進位 octal
10進位 decimal
16進位 hexadecimal
n進位 base n
長除法 long division method
次方法 power method

2014年5月9日 星期五

file system tradeoffs

有關檔案系統諸多設計取捨的優缺點摘要:

A.硬碟目錄結構(directory structure)的發展歷史:
1.一代單層(不利同名及分群)
2.二代雙層(仍不利分群)
3.三代樹(不利分享)
4.四代無循環圖形(利於分享)

註:系統要如何避免無循環圖形(acyclic graph)變成一般圖形(general graph),而造成不利走訪?
   解法為只允許一個實連結,其餘採虛連結(捷徑),走訪時忽略虛連結.

B.網路檔案系統協定能作到斷線復原快的作法分類:
1.有狀態(stateful):  建立會談耗時,但之後的額外資料傳輸量少,且安全.其復原快的原因為雙方皆留存斷線前狀態
2.無狀態(stateless): 不建立會談省時,但之後為了自給自足,額外資料傳輸量多,且不安全.其復原也快的原因為雙方根本沒有什麼狀態要復原

C.網路檔案系統協定有關檔案修改一致性(consistency semantics)的作法分類:
1.unix一致性(unix semantics): 修改馬上他人可見,因只有一份,故取用慢
2.會談一致性(sesseion semantics): 修改要稍後開始的會談才可見,因有多份,故取用快
3.唯讀一致性(immutable-shared-files semantics): 唯讀不能修改,故具一致性

參考:
silberschatz-13-wiley-operating system concepts, 9th ed.

2014年5月3日 星期六

how to set up mahout 0.5 taste-web web service

mahout 0.5 taste_web網站服務建置法 
----------------------------------

前言:

 因為mahout新版不再提供taste_web網站服務建置範例,
 ssaroha特將mahout 0.5版的taste_web範例置於如下github網站,方便參考:
  https://github.com/ssaroha/mahout-recommender-webservice

 其目錄結構如下:
  ./mahout-recommender-service/
    .git/
    README  # 安裝說明
    create_service.sh # 建立新推薦網站服務指令
 mvn archetype:generate \
     -DarchetypeGroupId=org.apache.maven.archetypes \
     -DarchetypeArtifactId=maven-archetype-webapp \
     -DgroupId=com.mykidscart.mahout_service \
     -DartifactId=mahout_service \
     -Dpackage=com.mykidscart.mahout_service \
     -Dversion=1.0.0 \
     -DjarName=mahout_service \
     -Dsource=1.6 \
    mahout_service/
      pom.xml
      src/main/webapp/WEB-INF/web.xml # web-app/servlet/init-parm/parm-value決定推薦器
      src/main/java/com/mykidscart/mahout_service/RecommenderServlet.java
      src/main/resources/movies.dat # 3952 movies
      src/main/resources/ratings.dat # 1M movie ratings of 6K users
      target/mahout_service.war

  預設推薦器為org.apache.mahout.cf.taste.example.grouplens.GroupLensRecommender

以下為復原taste_web範例步驟:

 # 建立git用戶身份,可作可不作
 # git config --global user.name "yyy zzz"
 # git config --global user.email "xxxx@gmail.com"
 # git config --global credential.helper cache
 # git config --global credential.helper "cache --timeout=3600"

 # 在當前目錄復原 ./mahout-recommender-service/ 架構
 git clone https://github.com/ssaroha/mahout-recommender-webservice.git

 # 產生 target/mahout_service.war
 cd ./mahout-recommender-service/
 mvn package

 ### 添加資料檔供讀取
 cp src/main/resources/movies.dat target/classes/org/apache/mahout/cf/taste/example/grouplens/
 cp src/main/resources/ratings.dat target/classes/org/apache/mahout/cf/taste/example/grouplens/
 mvn package

 ######## 測試法1: jetty ##############
 # 導入jetty插件,提供.war執行功能
 vi pom.xml
   <project>
     <build>  
       <plugins>
         <plugin>
           <groupId>org.mortbay.jetty</groupId>
           <artifactId>jetty-maven-plugin</artifactId>
           <version>7.1.2.v20100523</version>
           <configuration>
             <webApp>${project.build.directory}/${project.artifactId}.war</webApp>
           </configuration>
         </plugin>
       </plugins>
     </build>
   </project>

 # 用jetty啟動.war推薦服務
 mvn -Djetty.port=7070 jetty:run-war

 # 用瀏覽器測試推薦服務
 lynx http://localhost:7070/RecommenderServlet?userID=111&howMany=400

 ######## 測試法2: tomcat ##############
 # 部署 mahout_service.war 到 tomcat 網站
 # cp ./target/mahout_service.war  apache-tomcat-7.0.28/webapps/
 # unzip  -d mahout_service ./mahout_service.war
 
 cp ./target/mahout_service.war /usr/share/tomcat6/webapps/
 # unzip  -d mahout_service ./mahout_service.war

 # 用瀏覽器測試推薦服務
 lynx http://localhost:8080/mahout_service/RecommenderServlet?userID=111&howMany=400
 5.5 3233
 5.3458047 557
 5.0 134
 5.0 1434
 4.93471 3245
 4.899492 2503
 4.816771 2198
 4.815301 3888
 4.788968 53
 4.77251 787
 4.75434 3338
 .....