Total Pageviews

2017/07/11

Utilize AgeFileFilter to filter either newer files or files equal to or older

Scenario
I have an requirement to read a specific directory (including subdirectories) to find five days before log files and delete them.
How to do it?

How-To
Add commons-io to your maven dependency:
1
2
3
4
5
    <dependency>
     <groupId>commons-io</groupId>
     <artifactId>commons-io</artifactId>
     <version>2.5</version>
    </dependency>


Here has code snippet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    /**
     * 找出某個日期以前的檔案.
     * 
     * @param directory 找出某個目錄下的檔案
     * @param days 找出數天前 (如 -20)
     * @param includeSubdir 是否包含子目錄 (true / false)
     * @return List of File
     */
    public static List<File> getFilesBeforeXDays(File directory, int days, Boolean includeSubdir) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.DATE, days);
        cal.set(Calendar.HOUR, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        Date date = cal.getTime();

        IOFileFilter ageFileFilter = FileFilterUtils.ageFileFilter(date);
        IOFileFilter subDirFilter = includeSubdir ? FileFilterUtils.trueFileFilter()
                : FileFilterUtils.falseFileFilter();

        Collection<File> fileCollection = org.apache.commons.io.FileUtils.listFiles(directory, ageFileFilter, subDirFilter);
        if(CollectionUtils.isEmpty(fileCollection)){
            log.info("Cannot find any log files before " + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS").format(date));
        } else{
            log.info("Find " + fileCollection.size() + " log file(s).");
        }
        
        return new ArrayList<File>(fileCollection);
    }




Reference
[1] https://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/filefilter/AgeFileFilter.html    

2017/07/10

How to Clear Code Coverage Highlight in Eclipse

Problem
I am using EclEmma, a free Java code coverage tool for Eclipse, to generate code coverage analysis report. The report looks like:


EclEmma provide source highlighting to show the result of code coverage. If I would like to clear code coverage highlight, how to do it?


How-To
Click "Remove All Sessions" in Coverage tab



2017/07/09

[HttpClient] Fail to Get Response from a Valid URL

Problem
I am using HttpClient Get method to retrieve the response body of the HTTP method, if any.
During the execution, I fail to get response from a valid URL. 

The code snippet is as follows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package albert.practice.http;

import java.io.IOException;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Charsets;
import com.google.common.base.Strings;

public class HttpSmsClient {

    private final static Logger logger = LoggerFactory.getLogger(HttpSmsClient.class);

    public static String getResponse(String url) throws IOException {
        String responseString = "";
        HttpClient client = new HttpClient();
        
        GetMethod method = new GetMethod(url);
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                new DefaultHttpMethodRetryHandler(3, false));

        int statusCode;
        try {
            statusCode = client.executeMethod(method);            
            if (HttpStatus.SC_OK == statusCode) {
                responseString = IOUtils.toString(method.getResponseBodyAsStream(), Charsets.UTF_8);
            }
        } catch (IOException e) {
            throw e;
        } finally {
            method.releaseConnection();
        }
        logger.info("responseString = " + responseString);
        return responseString;
    }

}



How-To
In my office, I need to specify proxy server before I connect to various services.
Therefore, the source code will be modified as follows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package albert.practice.http;

import java.io.IOException;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Charsets;
import com.google.common.base.Strings;

public class HttpSmsClient {

    private final static Logger logger = LoggerFactory.getLogger(HttpSmsClient.class);

    public static String getResponse(String url, String proxy, String port) throws IOException {
        String responseString = "";
        HttpClient client = new HttpClient();

        HostConfiguration hostConfiguration = client.getHostConfiguration();
        hostConfiguration.setProxy(proxy, Integer.valueOf(port));
        client.setHostConfiguration(hostConfiguration);
        
        GetMethod method = new GetMethod(url);
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                new DefaultHttpMethodRetryHandler(3, false));

        int statusCode;
        try {
            statusCode = client.executeMethod(method);            
            if (HttpStatus.SC_OK == statusCode) {
                responseString = IOUtils.toString(method.getResponseBodyAsStream(), Charsets.UTF_8);
            }
        } catch (IOException e) {
            throw e;
        } finally {
            method.releaseConnection();
        }
        logger.info("responseString = " + responseString);
        return responseString;
    }

}


Maven dependencies are as follows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    <dependencies>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.7</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-httpclient/commons-httpclient -->
        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>20.0</version>
        </dependency>
    </dependencies>




2017/07/08

[HttpClient] Warning: Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended.

Problem
I am using HttpClient Get method to retrieve the response body of the HTTP method, if any.
During the execution, the console print this warning message: 
Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended.

The code snippet is as follows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package albert.practice.http;

import java.io.IOException;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Strings;

public class HttpSmsClient {

    private final static Logger logger = LoggerFactory.getLogger(HttpSmsClient.class);
    
    public static String getResponse(String url, String proxy, String port) throws IOException {
        String responseString = "";
        HttpClient client = new HttpClient();

        if (!Strings.isNullOrEmpty(proxy) && !Strings.isNullOrEmpty(proxy)) {
            HostConfiguration hostConfiguration = client.getHostConfiguration();
            hostConfiguration.setProxy(proxy, Integer.valueOf(port));
            client.setHostConfiguration(hostConfiguration);
        }
        
        GetMethod method = new GetMethod(url);
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                new DefaultHttpMethodRetryHandler(3, false));

        int statusCode;
        try {
            statusCode = client.executeMethod(method);
            if (HttpStatus.SC_OK == statusCode) {
                responseString = method.getResponseBodyAsString();
            }
        } catch (IOException e) {
            throw e;
        } finally {
            method.releaseConnection();
        }
        logger.info("responseString = " + responseString);
        return responseString;
    }

}


How-To
This warning message results from Line 38
According to its recommendation, the source code will be modified as bellows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package albert.practice.http;

import java.io.IOException;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Charsets;
import com.google.common.base.Strings;

public class HttpSmsClient {

    private final static Logger logger = LoggerFactory.getLogger(HttpSmsClient.class);

    public static String getResponse(String url, String proxy, String port) throws IOException {
        String responseString = "";
        HttpClient client = new HttpClient();

        if (!Strings.isNullOrEmpty(proxy) && !Strings.isNullOrEmpty(proxy)) {
            HostConfiguration hostConfiguration = client.getHostConfiguration();
            hostConfiguration.setProxy(proxy, Integer.valueOf(port));
            client.setHostConfiguration(hostConfiguration);
        }
        logger.info("url = " + url);
        GetMethod method = new GetMethod(url);
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                new DefaultHttpMethodRetryHandler(3, false));

        int statusCode;
        try {
            statusCode = client.executeMethod(method);
            logger.info("[getResponse] statusCode = " + statusCode);
            if (HttpStatus.SC_OK == statusCode) {
                responseString = IOUtils.toString(method.getResponseBodyAsStream(), Charsets.UTF_8);
            }
        } catch (IOException e) {
            throw e;
        } finally {
            method.releaseConnection();
        }
        logger.info("responseString = " + responseString);
        return responseString;
    }

}


Maven dependencies are as bellows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    <dependencies>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.7</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-httpclient/commons-httpclient -->
        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>20.0</version>
        </dependency>

    </dependencies>




2017/07/07

[webMethods] How to delete threads in webMethods

Problem
假設在 OpcTest 此 package 中會執行數個 flow services

若希望在 package 被 disable 時,能把這幾個 flow services 的 threads 砍掉,該如何做?


How-To
解決方式如下,共有兩個步驟:
Step 1. 建立一個 Java Service,source code 如下:
public static final void terminationService(IData pipeline) throws ServiceException {
        IDataCursor pipelineCursor = pipeline.getCursor();
        String threadNameToKill = IDataUtil.getString(pipelineCursor, "threadNameToKill");
        pipelineCursor.destroy();
        
        if(threadNameToKill == null)
        {
            // Fill in the toppest folder name.
            // Take the OpcTest package for example, it should be "group1".
            threadNameToKill = "group1";
        }
        
        Thread current = Thread.currentThread();
        ThreadGroup root = current.getThreadGroup();
                
        while (root.getParent() != null) {
            root = root.getParent();
        }
        
        Thread [] threads = new Thread[1000];
        int count = root.enumerate(threads, true);
        
        for(int i = 0 ; i < count ; i++)
        {
            if(threads[i] instanceof ServerThread)
            {
                ServerThread temp = (ServerThread) threads[i];
                
                String threadName = temp.getName();
                
                logger( "[ Thread Name ]: " + threadName);
                if(threadName.contains(threadNameToKill))
                {
                    logger( "[ Stopping ]: " + threadName);
                    threads[i].stop();
                }
        
            }
        }       
            
    }

Step 2. 將此 Java Service 設定為 shutdown service,如此一來,當 package 被 disable 或 integration server 被 shutdown 時,都會執行此 shutdown service





2017/07/06

[webMethods] Service 'group2.test:TestSubscriber' is not operational. To run this service, first recompile the Java source.

Problem
當我在執行 Flow Service 時,出現此錯誤
1:  [ISS.0059.0001W] Interrupted [ISS.0026.9102] Service 'group2.test:TestSubscriber' is not operational.   
2:  To run this service, first recompile the Java source.  


How-To
會出現此錯誤,是因為 webMethods 沒有 compile 此 Java Service,此時要強迫 webMethods 去 compile Java Service

執行步驟:
Step 1. 打開命令提示字元,變更目錄到 [integration server directory]\instances\default\bin

Step 2. 執行 jcode 來做強迫 compile OpcTest2 此 package 下的所有 Java Services,指令如下 jcode makeall [package name]
1:  D:\SoftwareAG\IntegrationServer\instances\default\bin>jcode makeall OpcTest2  

Reference
[1] https://docs-old.servicerocket.com/display/WMFAQ/How+to+make+a+Java+service+recompiled+even+if+it+hasnt+been+changed

2017/07/05

[Windows] Utilize netsh Command to configure TCP/IP

Frequently used commands are the following:

Show IP configuration
netsh interface ip show config


Configures the interface named 區域連線 with the static IP address 192.168.0.100, the subnet mask of 255.255.255.0, and a default gateway of 192.168.0.254:
netsh interface ipv4 set address name="區域連線" source=static address=192.168.0.100 mask=255.255.255.0 gateway=192.168.0.254


Configuures primary and secondary DNS:
netsh interface ipv4 add dnsserver "區域連線" address=10.160.1.9 index=1
netsh interface ipv4 add dnsserver "區域連線" address=10.160.128.9 index=2


Configures static IP address to DHPC:
netsh interface ip set address "區域連線" dhcp


Clear DNS configuration
netsh interface ip set dns "區域連線" dhcp

2017/07/04

[webMethods] 打開 Java Services 出現 source not available

Problem
當我將開發好的 package export and import 到另外一台 integration server,另外一外工程師無法看到我開發好的 Java Services,在其 designer 中出現 source not available 的錯誤,但是我卻可以看到,沒有遇到相同的問題

How-To
目前發現有兩個解決方式:
  • 由於我的 Java Services 中的程式註解有寫繁體中文,另外一位工程師可能是 Windows 語系設定與我不同的關係,導致在他的電腦中,無法看到 Java Services 的內容,當我將繁體中文的註解改成英文以後,此問題就解決了
  • 由於不明原因造成,重開 designer 之後,就可以看到 Java Service 的內容



2017/07/03

[webMethods] 如何將 export 的 package zip file,import 到另外一台 integration server

Problem
假設我們有多台 integration servers,根據不同用途分成開發機、測試機與正式機等,當我們從開發機的 integration server export 程式以後,該如何 import 到測試機 ?

How-To

前置步驟:將 package export 成 zip file


以下是 Import 執行步驟:

Step 1. 將 zip file 複製到 測試機 的 integration server 的 inbound 目錄下,路徑為 [IntegrationServer dir]\instances\default\replicate\inbound


Step 2. Login 到 Integration Server 的管理介面,點選 Packages => Management => Install inbound Releases



Step 3. 選取 Release file name,點選 Install Release


Step 4. 安裝完成後,會出現安裝成功的訊息,點選 Return to Package Management

此時,可以在 Package List 找到 ImportTest 此 Package


Refresh Designer 之後,也可以找到 ImportTest 此 package 及程式




2017/07/02

[閱讀筆記] 惡魔財經辭典 (The Devil’s Financial Dictionary) [3/6]


  1. Credit 是借貸,通常是只公司的借貸。貸方對借方的信任或信賴最好是建立在研究調查的基礎上,而不是建立在希望和祈禱
  2. Crown-jewel defense(皇冠寶石防禦),指的是企業抵抗惡意收購的方法,即賣掉最令人垂涎的業務,好讓自家的賣相便差,因而較有可能維持獨立自主。要保住自己的飯碗,還是保住公司最賺錢的資產?針對這個選擇題,公司經理人才選擇前者。股東的選擇或許不一樣,但是沒人問他們意見
  3. Cyclical stock (景氣循環股)是指產品或服務有週期性的公司,包括飯店業、製造業、營建設備製造商等。經濟衰退時,消費者購買力減少,這類公司就會受到連累;但經濟復甦時,消費者購買力增加,這類公司就會受惠。
  4. 選擇權(option)的價值衍生自股價變化;期貨(futures contract)衍生自大宗物資(commodities)或貨幣;交換(swap)則是以利率或另一個指數為基準的衍生性金融商品。這些都是衍生性商品(derivative),它可以控制風險,也會製造風險。正確使用適合的衍生性商品(derivative),可以降低風險、增加報酬,但若運用錯誤,也可能把投資組合炸得粉碎。若再結合槓桿操作(leverage),不當的衍生性商品(derivative)操作會江整個金融市場帶到熱核溶解邊緣
  5. dip 代表短淺的市場價格下跌,投資人若是認為「逢跌買進」(buying the dips)是獲利訣竅,那你就要小心,1929年股市大崩盤的前幾天、2008年的金融危機爆發前幾天,都有 dip,但是不是所有的 dip 都會變成大災難
  6. 基金的公開說明書(prospectus)最後都會說:「過去的績效不保證未來的績效」。其背後的意思是,不會因為過去獲利就降低未來「虧損」的可能
  7. Discounting(貼現)是一種人類衝動的過程,將未來的風險和報酬折換成現在的價值,寧願現在就享受到有錢的快感,也不願日後在享受更有錢的快感。投資人如果不用高額折扣去貼現(discounting)未來收益,而是用耐心、自制力等待數十年,等到收益開花結果,長期來看,獲得的效益最高
  8. 經濟學家 Keynes 曾說:「想儘快得到結果,是人類的天性。人類特別熱愛趕快賺到錢,一般人會用很高的比例去貼現打折,將未來收益折換(discounting)成馬上可以入手的收益。」
  9. 投資人容易增加自己的稅賦、減少投資報酬,因為他們太快賣掉賺錢部位,而虧損部位又持有太久。出脫一筆投資有了結一個「心理戶頭」(mental account)的心理作用,因此大多數投資人傾向儘快賣掉獲利部分,讓錢進口袋才安心,享受獲利的驕傲感。相反地,出脫虧損等於是讓虧損成為無法逆轉的事實,阻止未來轉虧為盈的機會,而且等於承認自己犯錯,所以大部分投資人都會把虧損藏起來,假裝不存在
  10. Diversitfy(分散投資風險、多樣化投資),目的是讓投資組合更加安全,投資組合多樣化,風險和報酬互有消長。要達到投資多樣化,就必須持有「有的會讓你歡喜、有的讓你憂」的標的
  11. 如果投資人買股票只是為了拿到股利,可能某天會猛然發現自己買到一頭幾不出牛奶的母牛,而且骨瘦如柴,也沒辦法宰來吃
  12. Dog (狗股)是華爾街動物園裡最令人討厭的動物,dog 是指老是不漲的股票,只聽的懂 down 這個指令
  13. Dollar-cost averaging(定期定額投資法),是指利用轉帳方式定期將固定金額投入共同基金等等資產,通常是每月一次。由於定期定額投資法不需顧及何時購買、花多少錢買,因此可以排除投資時的大部分情緒
  14. Benjamin Graham 在 1962 年寫道:「不管從何時開始,dollar-cost averaging 這個投資方法最後一定會成功,前提是必須認真、勇敢地確實執行。」這絕對不是一個小小的但書,這個前提假設是『一個能執行定期定額執行法的人,一定是個與眾不同的人。它不會受制於伴隨歷代股市循環而來的狂喜和憂鬱,這點很難做到』
  15. 投資人在投資之前應該把歷史上的最大跌幅乘以二,然後問問自己是否承受的起這樣的跌幅
  16. 比起經營(manage)公司,有些企業高層更重視的是經營公司的盈餘(earnings)數字。所以常發生盈餘不是少報(譬如不喜歡繳稅的老闆會少報,不想讓以後數字難看的經理人也會),就是多報(譬如想謀求大比分紅的經理人會多報,或是想按耐沒耐心的投資人時也會)
  17. 每當股票發生營利不符預測(earnings surprise)時,可能就讓股票在幾分鐘之內跌掉兩成,甚至更多。數十年來已有數不清的盈餘顯示,分析師連幾塊錢的預測誤差都做不到,更遑論幾毛錢的誤差
  18. EBITDA (Earnings Before Interest, Tax, Depreciation and Amortization)是指息前稅前折舊攤銷前盈餘,這是bullshit earnings,彷彿利息、稅都不重要似的,就算借貸支出多一倍,EBITDA 仍舊不變
  19. Efficient Market Hypothesis (效率市場假說)認為,不論哪個時間點,市場價格(price)會充分反映證券價值(value),因為相關訊息會立即納入市場,理性的投資人會不斷根據最新發展來調整自己對股價的期望。可是實務上,不論訊息的相關性如何,投資人不是視而不見,就是過度反應
  20. ETF (Exchange-Traded Fund) 是指數型股票基金,其交易成本很低,你可以買幾種分散的 ETF,聞風不動的持有數十年,最後就會致富,不過這樣做很無聊,所以投資人與投顧會卯起來買賣ETF,這麼做只會肥了投顧的荷包,而市場則照例做他該做的事,把財富從交易頻繁者手中轉移到耐心等候者的手中
  21. 唯恐天下不亂的金融界把立意良善的 ETF 複雜化,搞到 ETF 變成一個餿主意,還推出反向 ETF (inverse ETF) 可以買,跟其追蹤的指數每日報酬相反;甚至還有槓桿反向ETF(leveraged inverse ETF),除了操作方向與指數相反,還會成以兩倍或三倍,如三倍槓桿反向ETF,若指數賠1%,你會賺3%,若指數賺1%,你會賠3%。記住,投資工具越單純越好
  22. 一個人常說『不抱任何期待是一種福報,因為他絕不會失望』,這其實是有點憤世嫉俗的味道
  23. Fallen angel (墮落天使股)是指曾經一飛沖天的股票,如今墜落地面;或是曾經是高評等債券,如今淪為 junk bond。但是投資人總是很天真的相信他們會再上漲,只不過 stock 或 bond一旦重重衰落地上,要重返金融天堂就天遙路遠了
  24. 投資人往往認為 falling knife (落刀股)跌了九成以後,頂多剩下一成可以跌,其實不然,一股 100 元的股票跌九成到 10 元,很容易會在跌九成到 1 元,然後再跌九成到 0.1 元,後續還可能跌個不停
  25. 平均來看,盡可能把手續費壓低的投資人,最有可能賺到錢,而對於他們的金融顧問來說,則恰好相反
  26. 在真實世界裡,無論是天氣預報或運動比賽預測,做預測的人通常都會估算自己猜對的可能性。反觀華爾街,卻幾乎從未提出自己預測的或然率
  27. 要創造龐大財富,需要膽大心細與謹慎,而一旦獲得財富,還需要多十倍的智慧才能保住
  28. 強烈想追求獲利的人,最不可能獲利,反倒是耐心等候的人,最有可能獲利
  29. Greater fool theory (最大笨蛋理論)是一種信念,相信不論你用多麼愚蠢的價格買進股票之類的資產,一定找得到笨蛋願意用更高的價格跟你買。這世上不缺笨蛋,不過要是你老是指望每次需要笨蛋的時候就找得倒,有一天你醒來會發現,其他人都變聰明了,而那個笨蛋就是你
  30. Halo effect (光環效應)是指對人事物的某一種認知判斷,會連帶影響對相關事物的觀感。如果一家公司的股價強勢上揚,負責經營那家公司的人就會讓人覺得近乎超人。反制 halo effect 的方法是,利用 checklist 來個別思考公司每個環節

2017/07/01

[閱讀筆記] The Black Swan: The Impact of the Highly Improbable (2/3)


  1. 人為什麼都喜歡看數字,因為數字可以消除對於不確定性的焦慮感。但是這些預測的數字的正確性呢?
  2. 無論是企業或是政府的預測報告,都有一個很明顯的缺失,沒有註明其預測的錯誤率
  3. 預測常犯的錯誤是,人們過度重視預測的結果,卻不注意預測的精確度。精確度的重要性遠大於預測本身。例如天氣預報總是會有誤差,所以會跟你說本日溫度約20~26度之間
  4. 典型的發掘的模式是:你根據你所知道的去尋找事物,你卻找到你之前不知道的。例如要找通往印度的路線,卻找到美洲大陸。很多的發明,都不再當初預測中,卻大大的改變世界
  5. Three body problem (三體問題):雙星是十分常見的恆星系統,若再添加一顆行星,則變成難解的三體系統。亦即一體的初始位置若有一個微小的變動,後來的狀態可能會有極大的不同。遺憾的是,我們所處的世界,比三體問題還要複雜
  6. 這個世界是複雜的,人類是非理性的,沒有所謂的股市配置最佳化的組合
  7. 我們常用過去的經驗,推導出規則,並預測未來。但是,問題是,根據過去的事情來推測未來,受到我們過去所學與經驗的影響很大,很有可能兩個人得到完全相反的結果。例如,你一覺醒來還活著,你可能:(1) 你可能會長生不老、(2) 你更接近死亡一步
  8. 預測的最大盲點是,你把明天當作另外一個昨天來做預測
  9. 我們的問題不只是我們對未來一無所知,我們對於過去已經發生的事情,也沒有非常了解
  10. 不用對經濟學家或政府單位所做的經濟預測太過認真,把他們當成藝人在娛樂你就好
  11. 了解你無法預測,不代表你無法從不可預測的事情中從中得利。記住,你的底線是:做好準備!
  12. 在製藥業有很多正向意外(positive accident),研發出治療A的藥物,卻發現也能治療B。在人生中,你要盡量去trial and error,將獲得正向意外的機運最大化
  13. 黑天鵝有分好的黑天鵝與壞的黑天鵝,壞的黑天鵝會在你非預期下給你重擊,且產生巨大的傷害、難以翻身;如果你可以損失小錢、賺大錢,這就是好的黑天鵝,出版業、科學研究與創投這些領域。只要不利的因素是小的且容易被控制的,你反而要歡迎這種好的黑天鵝,你或許有機會獲得意外的收穫
  14. 不要想要精準的預測黑天鵝,與其去做預測,不如做好準備工作,當機會來臨時,抓緊機會
  15. 黑天鵝的特性是不對稱性 (asymmetry)。我們對於未來,永遠不知道自己不知道什麼,因為它本身就是未知 (unknown)。但是,你要總是猜測有可能那些事物會如何影響你,你的決策就要圍繞著這些可能的影響因素做防範
  16. 面對不確定性的中心思想是,你要聚焦於發生這個罕見事件會有什麼後果,而不是發生的機率。例如我們無法得知地震發生的機率,但是我們可以想像、模擬地震發生時,可能會產生的後果,提前做好防禦措施,減輕人員、經濟及建物等損失
  17. 面對不確定的投資環境,你要做好發生market crash的準備,把一些低風險的投資標的在你的投資組合中佔有一定比率,才不會黑天鵝發生時,一敗塗地,無法翻身
  18. 現在的世界就是一個不公平的世界,這就是所謂的馬太效應 (Matthew Effect),即富者愈富,貧者愈貧
  19. 1957年時期的500大公司,到現在只剩下74家還在這個名單中;S&P500 經過了40年,少部分因為購併而消失,剩下的不是萎縮或是走向破產的命運
  20. 冪次法則(Power law),可以用80/20 rule來理解。80%的財富由20%的人掌握,股票市場80%的人賠錢,20%的人賺錢,不管所得再怎麼平均分配,還是會往這個方向移動。那又如何才能成為那20%的贏家呢? 關鍵就在於千萬不要人云亦云,因為人是社會性的動物,跟著群眾走,缺少獨立思考的能力,只會讓你往80%靠攏