2013年11月11日 星期一

ubuntu上安裝Hadoop

此時hadoop的最新版本有三個分支
  • 0.23.0
  • 1.2.1
  • 2.2.0
千萬記得這三種並非2.2.0是最新的,而是0, 1, 2這三個大版號的三種分支,所以三種最新的版本。
網路上能看到的教學文章大致上是針對1.x的,而這篇內容也是如此。只是修正一些做法。
我目前用的環境是:

  • Mac OS X 10.9
  • VirtualBox 4.3.0
  • Unbuntu 13.04 64bit
  • Hadoop 1.2.1
  • Oracle JDK 1.6.0_45(目前跑出來的結果,事實上不一定要用Sun JDK,Oracle JDK一樣跑得很順利)
整個過程的步驟大致如下:
  1. 具有Virtualbox的環境,包含已安裝ubuntu(這裡不談此安裝步驟,記得安裝順便選SSH deamon)
  2. 安裝JDK
  3. 建立Hadoop用的user account,並且設定不需輸入密碼的SSH連線
  4. 安裝Hadoop
  5. 設定Hadoop
  6. 啟動單一個node的cluster,並且run一個sample
以上是single-node,接著是建立multi-node:
  1. 複製現有的VM
  2. 修改部份的設定
  3. 啟動multi-node的cluster,並且run一個sample
========================================================================
  • 安裝JDK
    移除所有的open JDK
    $ sudo apt-get purge openjdk*
    

    裝上來源並安裝JDK 6
    $ sudo add-apt-repository pap:webupd8team/java
    $ sudo apt-get update
    $ sudo apt-get install oracle-java6-installer
    $ javac -version
    

    此時會顯示出"javac 1.6.XXXXX",就應該沒問題了。
  • 建立Hadoop用的user account,並且設定不需輸入密碼的SSH連線
    因為Hadoop會要透過user account來SSH連線至其它主機,目的是能啟動並管理其它的子節點。

    建立user account
    sudo addgroup hadoop
    sudo adduser --ingroup hadoop hduser

    新密碼填完後,其它的資訊可以按enter對它視而不見。
    設定SSH的觀念比較深,這裡僅直接顯示指令,帶過觀念部份。

    $ su - hduser
    $ ssh-keygen -t rsa -P ""
    

    切換為hduser後,我們要建立一個不需輸入密碼的RSA key。過程中會請你輸入儲存key的檔案,直接按enter表示使用預設值。接著把這新的key用來SSH access本機。

    $ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
    $ ssh localhost
    

    第一次透過SSH access本機,請先同意ssh的連線,然後會發現不再需要打密碼了。

    *額外補充,以下的文章中,若使用sudo指令時,表示身份為創建系統的帳號,並不是hduser,基於安全的理由,它並沒有sudo的使用權限。若為懶人或實驗者,請使用:
    $ sudo adduser hduser sudo
    
  • 安裝Hadoop
    請直接到官網下載最新版的hadoop。這裡我是選擇1.2.1後,選擇裡面是tar.gz的壓縮檔,檔名內有bin和沒bin的差別是,沒bin的檔案比較大,包含有source code。我是下載bin的版本(如果不覺得浪費空間,那把source code下載下來研究也是不錯啦~~~~)。以下wget後面的字串,請直接copy檔案的下載位置即可~~~

    $ cd /usr/local
    $ sudo wget xxxxxxxxxxxx
    $ sudo tar xzf hadoop-1.2.1-bin.tar.gz
    $ sudo mv hadoop-1.2.1 hadoop
    $ sudo chown -R hduser:hadoop hadoop
    


    到這裡我們已經把檔案準備好了,接下來就是開始一些簡單的設定檔,然後就大功告成了~~
    接著要設定bash shell的環境變數:

    $ export HADOOP_HOME=/usr/local/hadoop
    $ export JAVA_HOME=/usr/lib/jvm/java-6-oracle
    $ export PATH=$PATH:$HADOOP_HOME/bin
    

    以上是bash的shell專用,其它shell請自行轉換。

    上述完成之後,必須再做一件小事,這個步驟是reference裡的教學提到的,因為IPV6會產生某些問題,因此保險起見,我們還是將Hadoop設定為使用IPV4較好。因為某些因素的關係,請先關掉IPV6的設定,但這的影響只在於Hadoop上,所以不需要把整個server的IPV6都關閉。

    $ echo "export HADOOP_OPTS=-Djava.net.preferIPv4Stack=true" >> hadoop-env.sh
    


  • 設定Hadoop


    接著先為Hadoop的config檔設定JAVA的環境變數,我們先找到"$HADOOP_HOME/conf/hadoop-env.sh",接著找到裡面的這一行

    # The java implementation to use.  Required.
    # export JAVA_HOME=/usr/lib/j2sdk1.5-sun
    

    改為

    # The java implementation to use.  Required.
    export JAVA_HOME=/usr/lib/jvm/java-6-oracle
    

    接著就是設定三個site.xml檔,這三個檔案分別為


    • $HADOOP_HOME/conf/core-site.xml
    • $HADOOP_HOME/conf/mapred-site.xml
    • $HADOOP_HOME/conf/hdfs-site.xml


    簡單的解釋,mapred就是map-reduce的意思,所以一定是用來控制運算的單元;hdfs也就是Hadoop file system,也就是用來控制分散式檔案系統的單元。那麼core換言之一定是核心內容的設定囉。以下我們分別加一些設定值到這三個檔案中的<configuration></configuration>內:

    conf/core-site.xml

    <property>
      <name>hadoop.tmp.dir</name>
      <value>/app/hadoop/tmp</value>
      <description>A base for other temporary directories.</description>
    </property>
    
    <property>
      <name>fs.default.name</name>
      <value>hdfs://localhost:54310</value>
      <description>The name of the default file system.  A URI whose
      scheme and authority determine the FileSystem implementation.  The
      uri's scheme determines the config property (fs.SCHEME.impl) naming
      the FileSystem implementation class.  The uri's authority is used to
      determine the host, port, etc. for a filesystem.</description>
    </property>
    

    conf/mapred-site.xml

    <property>
      <name>mapred.job.tracker</name>
      <value>localhost:54311</value>
      <description>The host and port that the MapReduce job tracker runs
      at.  If "local", then jobs are run in-process as a single map
      and reduce task.
      </description>
    </property>
    

    conf/hdfs-site.xml

    <property>
      <name>dfs.replication</name>
      <value>1</value>
      <description>Default block replication.
      The actual number of replications can be specified when the file is created.
      The default is used if replication is not specified in create time.
      </description>
    </property>
    


    經過上述昏頭的設定後,我們再回來看一下,在core-site.xml裡面,有一串字是"/app/hadoop/tmp",這表示Hadoop的檔案系統路徑,其實觀念就是我們給它一個目錄,然後這個目錄會被視為Hadoop的檔案系統,所以相關的內容、暫存檔等等的,都在這裡面,所以它"超級"重要。在上述的操作過程中,我們還沒開出這個目錄,原因就是要說這非常重要!!!!!當我們做了設計的更動,有發現些怪問題,我都是把它刪了再重新格式化(並非真的把我們的硬碟格式化,而是像virtualbox操作虛擬目錄一般,對這目錄初始化一些內容;"當然格式化後,原有的資料都會不見,請小心使用"),就解決了,感覺它就像有暫存參數般@@總之筆者對Hadoop也不熟,所以也說不出個所以然,再請看到這裡的Hadoop高手幫忙補充囉~~~

    首先新增一個目錄,然後為它設定正確的權限(權限沒設定好,過程出錯時,新手根本不知道問題是卡在這)

    $ sudo mkdir -p /app/hadoop/tmp
    $ sudo chown hduser:hadoop /app/hadoop/tmp
    $ sudo chmod 750 /app/hadoop/tmp
    

    當一切完成後,就是將這個目錄格式化,讓它成為Hadoop認得的設置。

    $ $HADOOP_HOME/bin/hadoop namenode -format
    

    當指令下完後,會看到格式化的內容,一切完成後,就表示你的機器"真的"可以開始跑Hadoop了,後簡單吧@@

    *這裡額外一提,格式化指令hadoop是整個hadoop的核心指令,幾乎所有的功能都當它加上參數(至少我這新手大部份時間都是用它囉~~~)。而Hadoop它就是讀到core-site.xml裡的路徑,得知file system的目錄在哪,並且將它初始化的。一旦我們執行這個指令時,筆者的電腦上會出現"Warning: $HADOOP_HOME is deprecated."的提示,別怕,這只是一個警告,網路上google一下就知道改的方法了,因為它並不會影響操作,就不把fix的方法放進來讓內容更亂囉~~


  • 啟動單一個node的cluster,並且run一個sample
    啟動時,只要簡單的執行以下指令即可。

    $ $HADOOP_HOME/bin/start-all.sh
    

    我們也能用指令
    $ jps
    

    看一下是不是真的該有的process都run起來了。照理來說會出現以下這些(順序不重要):

    5694 Jps
    5573 TaskTracker
    5243 SecondaryNameNode
    5343 JobTracker
    4787 NameNode
    5010 DataNode
    

    至於測試方法,請參考原著
    Running Hadoop on Ubuntu Linux (Single-Node Cluster)
    這也是本文主要的參考對象,大部份的內容可以說是簡化加英翻中,因為有些小地方實在得花太多時間猜測了,故才有這篇文章的出現@@

    當然我也做過它的
    Running Hadoop on Ubuntu Linux (Multi-Node Cluster)
    也是眉角不少@@吃很多虧。


待續。
這幾天會再補上"設定第二節點的過程"以及"running mahout"。


2013年11月7日 星期四

Spring MVC Restful JSON and XML

從Spring MVC 3.1開始,設定純Json或XML的response變得很簡單了。
  1. 以下是Maven pom file該加入的dependency
    (這是指選完Spring MVC template後,該額外加入的library)。
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-oxm</artifactId>
        <version>${org.springframework-version}</version>
    </dependency>
    
    <!-- Jackson -->
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>1.9.12</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.12</version>
    </dependency>
    
    <!-- marshaling and unmarshaling of XML data -->
    <dependency>
        <groupId>org.codehaus.castor</groupId>
        <artifactId>castor-xml</artifactId>
        <version>1.3.2</version>
    </dependency>
    

  2. 在Controller的method上加入@responsebody,並且把return type改成自已要的。

        @RequestMapping(value="/", method = RequestMethod.GET)
    @ResponseBody
    public Posts getAll() {     
        
        List posts = new ArrayList();
        
        Post p1 = new Post();
        p1.setId(1);
        p1.setValue(11);
        
        Post p2 = new Post();
        p2.setId(2);
        p2.setValue(22);
        
        posts.add(p1);
        posts.add(p2);
        
        Posts ps = new Posts();
        ps.setPosts(posts);
    
        return ps;
    }
    

    以下是Post POJO的內容。
    加上@XmlRootElement(name = "post")的用意是讓Spring MVC也能回應XML,而JSON是什麼都不用加即可運作。
    Mark掉的@XmlElement是讓你選擇要的property,如果都不加,預設是全部使用;一加上去後,就只會認有mark這個annotation的property。
    @XmlRootElement(name = "post")
    public class Post {
    //  @XmlElement
        private int id;
    //  @XmlElement
        private int value;
        
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public int getValue() {
            return value;
        }
        public void setValue(int value) {
            this.value = value;
        }
        
        @Override
        public String toString() {
            return "Post [id=" + id + ", value=" + value + "]";
        }
    }
    
    

    當我們需要傳List的時候,也可以把它封裝在POJO裡,這樣遇見的問題會比較少。
    @XmlRootElement(name = "posts")
    public class Posts {
        private List posts;
        
        public List getPosts() {
            return posts;
        }
    //  @XmlElement
        public void setPosts(List posts) {
            this.posts = posts;
        }
        
        @Override
        public String toString() {
            return "Posts [posts=" + posts + "]";
        }
    }
    
    
  3. 因為我從頭到尾都是用annotation來設定,因此如果你是從XML based的環境上來的,記得在servlet-context.html上加入一些內容。
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:beans="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    
        <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
        
        <!-- Enables the Spring MVC @Controller programming model -->
        <annotation-driven/>
        
        <context:component-scan base-package="com.test.restful.web" />
    </beans:beans>
    
其實3.1版的環境就真的這麼簡單就好了.....

另外說明一下,上述的code已經足以啟動XML或JSON的回傳內容。
基本上它會回傳哪一種格式,完全看Request Header的屬性"Accept"決定。
如果是"application/json"則回傳JSON格式,反之"application/xml"則回傳XML格式。
若同時出現,則看哪一個比較前面,便會以那個為預設值。

Reference: http://www.mkyong.com/spring-mvc/spring-3-mvc-and-xml-example/

2012年8月5日 星期日

tomcat default character encoding


in default Tomcat request, we can get null from request.getCharacterEncoding().

what's the default value from Tomcat?

the default value is ISO-8859-1, now we start to trace this path!!

reference:
http://www.docjar.com/html/api/org/apache/catalina/connector/Request.java.html

in method parseParameters():



 2496      protected void parseParameters() {
 2497
 2498           parametersParsed = true;
 2499
 2500           Parameters parameters = coyoteRequest.getParameters();
 2501
 2502           // getCharacterEncoding() may have been overridden to search for
 2503           // hidden form field containing request encoding
 2504           String enc = getCharacterEncoding();
 2505
 2506           boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI();
 2507           if (enc != null) {
 2508               parameters.setEncoding(enc);
 2509               if (useBodyEncodingForURI) {
 2510                   parameters.setQueryStringEncoding(enc);
 2511               }
 2512           } else {
 2513               parameters.setEncoding
 2514                   (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
 2515               if (useBodyEncodingForURI) {
 2516                   parameters.setQueryStringEncoding
 2517                       (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
 2518               }
 2519           }



if we don't add any configuration in /conf/server.xml, it will use default value.

==>

reference:
http://www.docjar.com/html/api/org/apache/coyote/Constants.java.html



the constant:
   27   public final class Constants {
   28
   29
   30       // -------------------------------------------------------------- Constants
   31
   32
   33       public static final String DEFAULT_CHARACTER_ENCODING="ISO-8859-1";



shows the default value for Tomcat character encoding!!

if you wanna change setting in server.xml, pls refer to https://confluence.atlassian.com/display/DOC/Configuring+Tomcat's+URI+encoding.

2011年3月4日 星期五

eclipse derby plug-in設定

一開始要先到Apache DB Project官網下載derby的檔案,目前的版本與路徑在

http://db.apache.org/derby/releases/release-10.7.1.1.cgi

進去後會看到

螢幕快照 2011-03-05 上午10.54.37.png

 

 

 

 

 

上面有很多種類型的檔案可以下載,但我們只需要這兩個for eclipse的~~

下載完後解壓縮會看三個資料夾名稱,分別是

org.apache.derby.core_10.7.1

org.apache.derby.ui_1.1.2

org.apache.derby.plugin.doc_1.1.2

這時候請別和我一樣雞婆,再進去這些資料夾裡,把它裡面的檔案一個一個抓出來,要記得直接將上述三個資料夾(_後的的版本可能會和你的不一樣,其它大致會相同)放到ecpilse安裝目錄內的plugins資料夾內,再重開eclipse就可以了。

接下來的安裝請參考輔大資管系eoffice版上的一篇文章~~

http://eoffice.im.fju.edu.tw/phpbb/viewtopic.php?t=6156

http://eoffice.im.fju.edu.tw/phpbb/viewtopic.php?p=24397

2011年2月28日 星期一

eclipse 自動完成 completion

在eclipse內,如果碰上平時使用alt+/可以出現的自動完成無法運作時,可以試試以下這個網址所述的:

 

http://stackoverflow.com/questions/908489/eclipse-java-code-completion-not-working

 

以英文版的eclpise而言,進入preferences -> Java -> Editor -> Content Assist -> Advanced,然後把東西勾一勾,如下圖就完成囉~~

 

螢幕快照 2011-02-28 下午10.59.13.png

2011年2月24日 星期四

ANTLR筆記

[ lexer | parser | tree ] grammer Name : ANTLR宣告,Name必須與檔名相同。

=====

options { ... } : ANTLR的設定值

  • language = Java; 此為預設值,改語言直接改等號右邊的內容即可,注意大小寫。
  • tokenVocab = xxxLexer for rule, or xxxParser for tree。

=====

@header { ... } : 產生出的java檔的表頭

  • 通常放import或package的定義等
  • 可以更進階的定義成 @parser::header { ... } or @lexer::header { ... },這樣就能分開定義在分開的檔案中。

=====

@members { ... } : 定義產生出的類別"成員與方法",也就是等於在裡面直接寫target language code的意思。

=====

若在重覆的規則中,要取得每個重覆的值,可以:

ee returns [int value]    
:   a1=INTT {$value+=Integer.parseInt($a1.text);}    
('+' a2=INTT {     
$value+=Integer.parseInt($a2.text);          
System.out.println($value);        
}
)+NEWLINE             ;

上述的重點在於a2的左右大括號必須在()+內撰寫,這樣才能取得每一次的值,否則在()+後寫,會只找到最後一個值。

=====

如果要取一個parser邏輯的所有內容,則可以使用$text即可。例如:
statement:
'if' parExpression a1=statement ('else' statement)?      {     System.out.println("node: " + "if");     System.out.println("status: " + "else");     System.out.println("statement: " + $a1.text);    
}

這裡的$a1.text是指第一個statement,但如果直接印出$text就會出現與這個規則符合的全部字串。

=====

 

 

 

 

 

 

在eclipse中,增加jvm的heap memory空間

在執行java程式時,碰上了錯誤是

java.lang.OutOfMemoryError: Java heap space

雖然知道是啥,但是不知道eclpise在哪改,事實上只要到run -> run Configuration,在(x)= Arguments的分頁內的VM argument中,輸入自己想要的空間即可~~

-Xmx512m

以上的意思是說,把heap memory設定為512MB。

 

附圖如下:

螢幕快照 2011-02-25 下午2.37.47.png

2011年2月2日 星期三

解決php存取mysql的亂碼問題

貼這三段在connect宣告的區塊
mysql_query("SET NAMES 'utf8'");
//要從資料庫顯示utf-8資料要加三行--第一行
mysql_query("SET CHARACTER_SET_CLIENT=utf8");
//第二行
mysql_query("SET CHARACTER_SET_RESULTS=utf8");
//第三行
搞定~~

2011年1月25日 星期二

flash loadvariable顯示&字元

說到這,flash真的很爛= =還得用這種爛方法....

如果用loadvariable讀取外部檔案來當作自己的資料時~~
通常是用:

loadVariables("xxx.txt", "xxxx");

然後xxx.txt裡面就可以這麼寫:

&title=xxx;
&name=xxx;

今天忽然要用到這種東西:

&school=A&M Texus

結果flash居然給我切開了 = =,試了\&,&&,"&"沒一個有用,最後發現是....

把&換成%26的編碼= =搞定= =(記得把txt檔改成utf-8的編碼,不然網路上說不會過,當然我懶得試...)

GOOGLE的搜尋字串為:"flash loadVariables escape &"
btw, 雙引號別忘了加,不然抓不到&這個字喔~~~

2011年1月22日 星期六

solving java heap space for antlrworks in mac

the cache default is 99M, but i need more. according to the website, just open antlrworks for mac bundle, and open Info.plist file using Property List Editor.

you will see the Infomation Property List -> Java, and just add new record with VMOptions as the Key and -Xmx512M as Value, save it. Enjoy it.

 

antlrworks在mac的預設cache大小為99,根據網站有人提供的作法,只要加個東東就ok了。將antlrworks用在mac平台的套件用右鍵選打開套件來打開,接著在選裡面的Info.plist,然後在java目錄中加上一筆設定,標頭打上VMOptions,數值打上-Xmx512M即可。

2010年12月8日 星期三

印聖誕樹

聽演講很無聊,就印了一個聖誕樹,聖誕節快樂!~~!

          *          
         ***         
        *****        
       *******       
      *********      
     ***********     
    *************    
   ***************   
  *****************  
 ******************* 
*********************
          *          
          *          
          *          
          *          


(還是在compiler印出來比較好看= =)

================== source code ===================


public class Main{
public static void main(String[] args) {
for(int i = 0; i<=10; i++){
for(int j = -10; j<= 10; j++)
if(Math.abs(j)<=(0+i))
System.out.print("*");
else
System.out.print(" ");
System.out.println("");
}
for(int i = 0; i<=3; i++){
for(int j = -10; j<= 10; j++)
if(j==0)
System.out.print("*");
else
System.out.print(" ");
System.out.println("");
}
}
}

2010年11月27日 星期六

Design pattern學習心得筆記(未完待續)

軟工上了一學期的課,每人輪流報了23個Design Pattern,但還是模糊不清,當然最終還是覺得靠自己最實在,以下是看了良葛格的Design Pattern後,所整理的最最重點,雖然他寫得不錯,但總覺得內文有些是翻譯過來的,非常不順...但還是感謝他!!

良葛格的Design Pattern連結

看了前三個Factory系列,抓到了一個Factory的重點,那就是Logic Hiding,怎麼說呢,其實聽到大部份人回應Design Pattern都會說,UML圖有看沒有懂,那是因為太強求我該如何用它才會這樣,其實我的想法是有fu就好了~~

Design Pattern具有三個大方向,分別是Creational Patterns, Structural Patterns 與 Behavioral Patterns 三種。

 

下面是關於第一種 Creational Patterns,也就是專門用來創造的,說白一點,就是在java裡的xxx x = new xxx()的new xxx() ==> 總之就是建立物件時候用的啦@@。

====================

  • Factory呢,我認為只要它出現,就會有敘述,factory.getXXXX(),或是xx.xxx(factory);。然後abstract factory是指在class這個觀點,而factory method只是一個class中,其中一個未實作的method罷了。其實主要的目的是將"確定要用的型別"定義在factory裡面,而這些型別一律採用interface的繼承方式(無論哪種語言啦,都是指最上層那個代表概念的介面就是了);所以當把型別繼承interface並且實作完成以後,就到factory內修改成(加入)這個型別...結束。
  • Builder有點麻煩,我自己也沒看得懂,反正就是和abstract factory差不多,不過他會與其它必須的"型別相依",如果有強者看見我的拙著,會的請用更簡單的話教教眾生吧,感謝...。
  • prototype就直接想成我們平常不是都用new xxx()嗎,但是這個new 的成本太大了(配置記憶體、加入當時環境並運算...反正就new一次要花很多時候在cpu上),這時候呢,我們就把原有已經new好的相同型別的,直接clone一個出來(也就是xxx的記憶體直接1對1複製,不用再算有的沒的),夠簡單吧。
  • singleton說明白點就是只準給你一個物件(實體),你再怎麼new xxx(),它回傳的指標都是一模一樣,酷吧,這個簡單到我偷笑了。

 

很快的就進入第二種 Structural Mode...

====================

  • Adapter就是把你要的項目包起來,以更通用的介面、或是更快捷更少量的實作達到更簡單使用的目的,所以UML圖裡面,才會使用一個target的介面,然後一個實作這個target介面的adapter包住你要用的項目adaptee。
  • bridge模式的重點在於將程式邏輯,和表現部份(ex: I/O)抽離,因為表示部份可能因為不同的版本而改變,但程式邏輯並不和這相關,當版本改變時又得重寫那不就哭哭了嗎,所以先做一個表現層次,接著在邏輯層次呼叫這些通用的表現介面,假設表示類別需要做修正,只需新增實作的表現介面即可。
  • composite的意思就是一個容器能儲存很多單一的個體,但是這個容器與個體的型別都必須實作一介面的方法,容器可用此方法作用於容器內的這群個體,而個體也能用此方法對自己作用,因此composite的關鍵在容器儲存的型別是介面型別,但事實上是儲存個體的型別實體,看起來很像是複合的。
  • decorator意指一的個能當作一個層次,然後新的功能就繼承上一代,說實在的這與傳統的想法沒有不同,就是一件事情一個層別負責,但它較具特色的部份是利用上一層級產出的資料加工,另一個重點是一般繼承不會將上一個介面放入自己的成員中。decoretor與composite很容易搞混,差別在於composite能讓物件具有獨立性或複合性,而decorator能在維持原有介面下依然能延展新的能力。
  • Facade提供更高層級的介面,它將複雜的實作藏起來,只提供更簡易的內容,簡單的說,就是再架一層更簡單的介面,然後此介面中再實作較多細節的內容。
  • Flyweight很簡單,只是將可以共同的物件,能不重覆,就不重覆的方式,我是覺得它比較不在乎速度,比較在乎容量~~畢竟做出一個新物件,就算拿去比較最快也得要O(1),但它的容量卻省很多~~
  • Proxy就是代理的意思,若是a物件的代理,則若要用到a時,請找proxya,proxya一定能傳達訊息給a,但是之中會做點事情,這個事情端看使用者如何定義,因此重點是proxy想代理的功能才是重點。

 

很快的就進入第三種 Behavior Mode...

====================

  • Chain of Responsibility就是將一連串的判斷行為拆成像鏈子的一串class,每個class都處理不同情況要反應的事,所以不用因為加一個或減一個,而動到很多結構。
  • Command的意義在於物件的加入和執行抽離,可以動態加入動作,再選擇執行的內容,不需要改很大。
  • Strategy的用意是在獨立不同的演算流程(演算法),來源是一樣的,它的流程是不同的,但演算流程之間是相似的,它與Command很像,但我自已的感覺是Command是依對象的不同,回應不同的請求,但是Strategy則是同樣的請求,但最後的處理與回應相似,只有中間的流程是不同的。
  • Template很像是限定好介面,然後等得之後實作它的內容,但它強調部份方法是實作時再進行,而一些已經預定的流程會先實作好,這樣就是在製作一個樣板的動作,好讓之後的人有個模型可以跟隨。
  • Observer在於建立物件集合發生變化時的反應,簡單的說可以視為訂閱者,能監看物件集合的內容,有何種變化該進行怎樣的通知等等。
  • Mediator能視為居中協調的角色,所有獨立物件之間不應該知道有其它人的產生,每人只需對Mediator負責即可,然後Mediator再視情況改變每一個人的狀態即可。
  • State是將原來相依性很強的結構邏輯拆開,讓State的子類別實體去決定該將旗號交給誰,而不是一個單一的個體控制全部,但怎麼變都是讓狀態設定為其中State一個子類別的實體罷了。

2010年11月23日 星期二

LCS 最長共同子序列(未完待續)

Longest Common Subsequence

  • 原來以為這是一個演算法,但它其實是個LCS的問題,目的在找出兩個以上的字串中,最長的共同字串。
  • 子字串與子序列的差別:子字串必須是字串中的連結部份,子序列則不是必需。

問題的定義

  • 有兩個長度為m的字串S,與長度為n的字串T,我們必須找到S與T中的最長子共同子字串,一般稱之為k共同子字串問題。給定一個字串集合S = {S1, ..., Sk},其中|Si| = ni且Sigma ni = N。2 ≤ k ≤ K,最長字串最少要有k長度。


解法有兩種,分別為suffix tree與dynamic programming,其中

  • suffix tree的量級分析為 O(n + m)
  • dynamic programming的量級分析為 O( nm )

2010年11月22日 星期一

cocoa入門(一)

應用程式、視窗與View的關係
================================================
  • NSWindow座落於NSApplication與View之間。
  • NSApplication可以管理多個視窗並追蹤它們的目前狀況。
  • 總之NSWindow管理一堆在它底下的View。
  • cocoa是以左下角為它的視窗定位座標原點,而carbon是在左上角。
製作GUI程式的心得
================================================
  • 在用interface builder讀取class時,別管錯誤訊息。
  • 類別內的成員連外介面的,會叫IBOutlet;介面連進來對應的方法會叫IBAction。
  • 用內建的document做第一個入門視窗程式很簡單,它的文件名稱為"Cocoa Application Tutorial",直接在文件的Search上搜尋就會有了。
  • 原來內建的Icon設計程式是在/Developer/Application/Utilities/Icon Composer就有了。

2010年11月21日 星期日

automator心得

網路automator的心得很多,但我看了其實也沒很了解

以下我用自己的話來說明automator的初步用法

=====================

先講工作流程、應用程式與服務三項吧!!

  • 工作流程
簡單的說,就是一個像word中的doc檔,只是存著下次開啟用的

  • 應用程式
可以把上述的工作流程儲存成一個應用程式,好處是你要用就開
不需要再經由automator執行

  • 服務
當編輯完後存檔,就會自已跑進~/Library/Service的目錄中,它
其實是座落於背景的服務(但還沒執行),例如:









這裡我選"任何應用程式"的"文字",接著我又選了文字套件中的
朗讀文字,目的是將輸入的文字唸一次,接著再存檔成speaker。
這裡的意思代表我能在之後的任一個應用程式中,使用到這一項服務。

假設在safari中,我選取一段文字,接著選擇左上角的safari ->
服務 -> speaker(存檔時的名稱),這樣就能將選取的文字唸出來了
。另一種方式是將文字選起來,再按右鍵選服務項目也可以。




新的開始@@

快畢業了,也該開始給社會一些貢獻!!

一星期來寫一篇吧@@

2009年4月3日 星期五

Tcl Extending

creating new TCL pakage from C source using swig

it’s created by me in my second year in my uni.

maybe it’s a little defect for the document ,don’t care plz!!! thx..

目前在世面上,大約有二種方法是較常用來擴充Tcl模組的方法,一種是利用Tcl目錄裡, include資料夾裡的.h檔來進行,大部份都只用到tcl.h, 也有tk.h是用來包給tk用的。

今天我要介紹的方法,是利用世面上一個叫做swig的軟體,它神奇之處在於你不必使用太繁複的方法宣告很多tcl.h的資料形態,你只需要以平常寫C的方式,寫出你要用的程式片斷,在底下我以example.c命名,並且寫出一個介面(interface),用來宣告在Tcl底下,Tcl如何來引用我的example.c,我把這個檔案命名為example.i,以下的操作環境為ubuntu 8.04,因為手邊暫時沒有windwos系統,請大家見諒。


first one

this is my new blog since now to future.