Total Pageviews

2017/09/02

[閱讀筆記] Common Stocks and Uncommon Profits (1/4)


  1. 投資目標應該是一家成長的公司,公司應當有按部就班的計劃使盈利長期大幅成長,且擁有很難讓新加入者分享其高成長的內在特質
  2. 集中全力購買那些失寵的公司。這是指因為市場走勢或當時市場誤判一家公司的真正價值,使得股票的價格遠低於真正的價值,此時則應該斷然買進。費雪有過教訓,在股市高漲的年代,買到一家成長股,但是由於買進的價格高昂,業績即使成長,但亦賺不了錢。
  3. 我們投資的是公司不是GDP,亦不是 CPI 或者定期存款利率。許多人信奉波段操作,但是至今沒有一個靠波段操作成為投資大師的
  4. 追求資本大幅成長的投資人,應淡化股利的重要性。獲利高但股利低或根本不發股利的公司中,最有可能找到十分理想的投資對象。成長型的公司,總是將大部分盈利投入到新的業務擴張中去。若大比例分紅,則多數是因為公司的業務擴張有難度,所以才將盈利的大部分分紅。
  5. 無論是公司經營還是股票投資,重要的是停損,而不是停利。許多投資者往往是做反了,買進一隻股票一旦獲利,總是考慮賣出;相反的,買進的股票套牢了便一直持有,讓虧損持續擴大。
  6. 股票投資,有時難免有些地方需要靠運氣,但長期來說,好運、壞運會相抵,想要 持續成功,必須靠技能和運用良好的原則
  7. 在熊市時,這是個去提升你持有股票品質的好時機,公司的素質在熊市時一覽無遺
  8. 當大家對於市場焦躁不安、瘋狂殺出時,你反而要憂心那些股票是你該擁有的,但是你卻沒有
  9. 購買股票前,你要考慮 15 個面向:
    1. 這家公司所提供的產品與服務,在未來數年間,是否有足夠的市場潛力來產生大量的銷售業績?【此點著重於公司現有產品的銷售成長潛力】
    2. 當現有的受歡迎的產品線的成長潛力出現停滯時公司的管理階層是否有能力持續開發新產品或服務?【此點著重於公司領導階層的能力與態度。其是否能從現有市場中,發展出有潛在需求的產品或服務,做為未來成長的動能】
    3. 公司是否有效利用其研發能力,如投入多少  R&D成本,帶來多少效益?【你可以研究一下這家公司在特定時間區間 (如過去十年),花多少錢在 R&D,以及貢獻多少銷售額或是淨利】
    4. 公司是否擁有優於一般公司的銷售組織?【企業成功的三大基石:生產 (production)、銷售 (sales) 與研發 (research),只有堅強的生產與研發團隊,是不夠的,若要有穩定、長期的成長,一個強大的銷售團隊是非常重要的】
    5. 公司是否有足夠的淨利 (profit margin)?【投資人要遠離低淨利的公司】
    6. 公司在維持或改善淨利上,做了甚麼努力?【靠漲價來維持或改善淨利,長期來說對投資人不是好事;好的公司,會思考新的點子、方法來降低成本與改善淨利,這才會是長久之道】
    7. 公司與員工間是否有良好的關係?【好的勞資關係,員工的就會擁有較高的生產力、比較高的向心力、較低的流動率,對於公司是正向的。若一家公司,很多人排隊去應徵、薪水高於該產業平均薪資以及高階主管是否善待基層員工,都是可以觀察的重點】
    8. 公司的高階管理階層與基層工作人員是否有良好的關係?【公司內部人員的升遷、調薪,是否有被公平對待,影響著內部的和諧、向心力與生產力】
    9. 一人管理 (one-man management) 的公司是無法持續成長的。【若公司要獲得更進一步的成長,最高主管有無培養接班人選、是否能傾聽別人的意見,都是值得注意的地方】
    10. 公司是否有良好的成本分析與成本會計?【沒有好的成本分析,就不會有好的訂價策略。成本會計分為管理及財務兩個方面,成本會計協助管理計劃及控制公司的經營,制定長期性或策略性的決策,並且建立有利的成本控制方法、降低成本與改良品質】
    11. 公司在此產業中,是否異於其他公司的特色或能力?【如擁有技術專利,可以在激烈的競爭中取得優勢、維持一定的毛利,但是要注意,當專利到期後,此保護傘就不見了】
    12. 公司有無短期或長期的獲利目標?【投資人要避免短視的公司】
    13. 公司是否擁有健全的財務來支撐公司未來的成長?【請記住,不要因為財務健全就投資此間公司,其還要滿足其他十四點條件】
    14. 公司的管理階層是否只有在經營狀況好的時候跟投資人說明狀況,但是在經營狀況不佳時,則三緘其口?【若是遇到問題,卻不跟投資人說清楚狀況,代表經營者也徬徨不安,對於問題沒有解決方法,也代表著對於股東毫無責任感,投資人應遠離這類型的公司】
    15. 公司的經營者是否有誠信?【若一家公司缺乏誠信,即使擁有極佳的經營績效,符合上述的14點說明,投資人仍應遠離這類型的公司】
  10. 挑選理專時,有兩個原則
    1. 理專必須誠實
    2. 理專的財顧管理的基本概念必須要跟你一致,如上述的15點。若理專與你的想法不一致,你最好換另外一個理專,因為若想法不同,其所挑選的投資組合,也不會是你想要的
  11. 在投資前,請準備好足夠的錢來面對可能會遇到的醫療費用、或是其他意外事件所衍生的額外費用。投資不保證賺錢,再怎麼訓練有素的投資人,也有可能誤判情勢
  12. 成長型的股票,不僅在同行中要有卓越的績效表現,其在股息回報率上,在同行中也會擁有卓越的表現
  13. 不要仰賴財經專家、機構所做的預測來投資,因為他們的預測,大部分都是錯的
  14. 當公司經營過程出現麻煩,此時你要判斷這對公司的影響是暫時的,還是永久的。如果只是暫時的,你可以考慮在投資大眾恐慌殺出時,酌量買進

2017/09/01

[閱讀筆記] The Long Tail (1/2)


  1. 不要一直想要征服大眾市場,因為那邊有太多強敵與競爭。一定要找到自己的利基,只要能夠把一群小眾的消費者顧好,你就會有很大的生存空間
  2. 市場上還是會有暢銷品,只是過去「只有」暢銷品,未來會被分成:有一些暢銷品,以及很多利基產品。暢銷品的市佔率從過去50%以上,可能會降至20%
  3. 眾多利基商品,以往因為不符合經濟效益,所以未能浮上水面,但這些商品其實存在許久,只不過不易為人見到或找到。舉凡各地戲院沒有上映的電影,各地廣播電台沒播的音樂。現在透過Google、Netflix、iTunes等等,以往隱形的利基市場終於浮上水面
  4. 如果說二十世紀的娛樂產業事由暢銷主導,那麼二十一世紀則是以利基分眾為馬首是瞻
  5. 促成長尾效應的三個力量
    1. 生產工具大眾化:過去只有專業人士才能做的事,現在人人都能做
    2. 配銷工具大眾化:網路降低了接觸更多顧客的成本,有效增加尾巴部分市場的流動性,進而促進消費、提高銷售量
    3. 連接供給與需求:如 Google 降低搜尋利基內容的『尋找成本』
  6. 被強迫、非自動、為薪資而做的勞動,將被自動自發的活動所取代
  7. 長尾的頭部與尾部生產者的差異,是愈靠近尾巴,就越可能必須保有一份正職的工作。「專業」與「業餘」生產者的界線已經日漸模糊,最終可能無關緊要。有的人為報酬而做,有的人為興趣而做,兩者皆可產生價值
  8. 即使99%的 blog 吸引的讀者不多,但是這 1% 能接觸到更多的讀者。這 1% 的 blog 的訪客總數不輸給主流媒體
  9. 長尾間的流動性日益增加,在暢行無阻的數位市場,從尾部開始的內容,如果能引起眾人共鳴,有可輕易移動到長尾的頭部
  10. 長尾市場最基本的原則是:銷售成本越低,銷售量越高。因此,aggregator 代表長尾市場的第二股力量,能促進配銷得大眾化。Aggregator 降低市場的進入障礙,讓更多商品越過障礙、流入市場、找到知音
  11. 今日的資訊取得,簡直易如反掌。搜集資訊不再是問題,如何根據資訊做出明智的決定,才是困難所在
  12. 第一股力量(生產工具大眾化)拉長了市場尾巴,第二股力量(配銷大眾化)讓人人都能進入長尾市場,第三股力量(個性化推薦),幫助人們在豐沛的選擇只選擇中找到他們要的,才能真正釋放長尾的澎湃潛力
  13. 在選擇無限的世界,真正的主宰是context (架構),而非content (內容)。現在的內容太多,你需要有一個 filter (篩選器),帶領人們從已知的世界(暢銷商品),走入未知的世界(利基商品)
  14. Filter (篩選器)的挑戰是,如何慧眼識英雄。如果你善用聰明的搜尋引擎、推薦系統或其他 filter ,就比較容易在長尾中挖到寶。filter 不但能為市場尾部的商品帶來需求,還能撮合人和商品,提升滿意度
  15. 在暢銷導向的世界,我們常高估暢銷商品占整體市場的比例。其實,暢銷商品反而是罕見的例外。這就是Nassim Taleb 提出的 Black Swan Problem
  16. Black Swan 是符合三項特質的隨機事件
    1. 影響重大: 事件的發生會造成重大影響
    2. 機率無法估算:根據事件尚未發生前的資訊,事件發生機率儘管很小,卻無法計算
    3. 出其不意:觀測時無確切跡象顯示事件發生機率會升高,但後來事情偏偏就是發生了
  17. Power-law distribution (冪次分佈) 是指,不管你要找什麼,沿著尾巴走,會出現越多你不要的東西。這就是為何訊號雜訊比會惡化,即使通常你必須走入長尾才能找到你要的東西。這就是 filter 要解決的問題
  18. Law of the Vital Few (重要少數法則):財富與人口的分佈,80%的財富為約20%的人所持有,這也是我們現在所說的80 / 20 法則


2017/08/11

[DB2] Use getNextException() to retrieve the exceptions for specific batched elements. ERRORCODE=-4229, SQLSTATE=null

Problem

When I using Apache Commons DBUtils to do batch insert data into IBM DB2, I get this SQLException:
1
2
3
SQL Message: [jcc][t4][102][10040][4.14.88] Batch failure.  
The batch was submitted, but at least one exception occurred on an individual member of the batch.
Use getNextException() to retrieve the exceptions for specific batched elements. ERRORCODE=-4229, SQLSTATE=null


Code Snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
    /**
     * 批次處理.
     * 
     * @param sql
     *            insert/update/delete sql statemet
     * @param params
     *            parameters
     * @throws SQLException
     *             in case of fail to do insert/update/delete
     */
    public void batchUpdate(String sql, Object[][] params) throws SQLException {
        QueryRunner run = new QueryRunner();
        run.batch(this.getConnection(), sql, params);
    }



How-To
According to the troubleshooting information from IBM Support, it said:
The error is caused by the DB2 Transaction log for the Data Warehouse becoming full and not able to process the full batch operation.


But the root case is "value too large" in insert SQL statement, having nothing to do with DB2 Transaction log.   

2017/08/10

How to Improve Code Coverage After Using Apache Lombok?

Problem
After using Project Lombok, we can find out it help use reduce our boilerplate code. 

 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
package albert.practice.lambda;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import com.google.common.base.Strings;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

public class LambdaTest {

    public List<Person> filterData() {
        List<Person> people = createData();
        return people.stream().filter(p -> p.age >= 35).filter(p -> !Strings.isNullOrEmpty(p.email))
                .collect(Collectors.toList());
    }

    public List<Person> filterDataWithSort() {
        List<Person> people = createData();
        return people.stream().filter(p -> p.age >= 35).sorted((p1, p2) -> (p1.age - p2.age))
                .sorted((p1, p2) -> p2.name.compareTo(p1.name)).collect(Collectors.toList());
    }

    public List<Person> createData() {
        Person ben = new Person("Ben Whittaker", 70, "ben@gmail.com");
        Person jules = new Person("Jules Ostin", 30, "jules@gmail.com");
        Person fiona = new Person("Fiona Farwell", 68, null);
        Person matt = new Person("Matt", 35, "matt@gmail.com");
        
        return Arrays.asList(ben, jules, fiona, matt);
    }

    @Data
    @ToString
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Person {
        private String name;
        private int age;
        private String email;
    }

}

But you will also notice your code coverage rate is down dramatically.


How to improve the code coverage rate?


How-To
Add two dependencies to your pom.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<dependencies>
    <dependency>
        <groupId>org.meanbean</groupId>
        <artifactId>meanbean</artifactId>
        <version>2.0.2</version>
    </dependency>

    <dependency>
        <groupId>nl.jqno.equalsverifier</groupId>
        <artifactId>equalsverifier</artifactId>
        <version>2.2.1</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Check the testPersonBean() and testEqualsAndHashCode() in this test case:
 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
53
54
55
56
57
58
59
package albert.practice.lambda;

import static org.junit.Assert.assertEquals;

import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.meanbean.test.BeanTester;

import albert.practice.lambda.LambdaTest.Person;
import lombok.extern.slf4j.Slf4j;
import nl.jqno.equalsverifier.EqualsVerifier;
import nl.jqno.equalsverifier.Warning;

@Slf4j
public class LambdaUnitTest {

    private LambdaTest lambdaTest = null;

    @Before
    public void setup() {
        lambdaTest = new LambdaTest();
    }

    @Test
    public void testCreateData() {
        List<Person> people = lambdaTest.createData();
        assertEquals(people.size(), 4);
    }

    @Test
    public void testFilterData() {
        List<Person> people = lambdaTest.filterData();
        log.debug("testFilterData = " + people.toString());
        assertEquals(people.size(), 2);
    }

    @Test
    public void testFilterDataWithSort() {
        List<Person> people = lambdaTest.filterDataWithSort();
        log.debug("testFilterDataWithSort = " + people.toString());
        assertEquals(people.size(), 3);
    }

    // Testing getter and setters methods
    @Test
    public void testPersonBean() {
        new BeanTester().testBean(LambdaTest.Person.class);
    }

    // Testing equals() and hashCode()
    @Test
    public void testEqualsAndHashcode() {
        EqualsVerifier.forClass(LambdaTest.Person.class)
                .suppress(Warning.STRICT_INHERITANCE, Warning.NONFINAL_FIELDS).verify();
    }

}

After running code coverage analysis, you can find out this problem had been solved:




Reference
[1] http://www.jdev.it/tips-unit-testing-javabeans/

2017/08/09

[Squirrel SQL Client] Is it possible to have Squirrel SQL auto-resize the column width of the result set?

Problem
Is it possible to have Squirrel SQL auto-resize the column width of the result set? 


How-To
Steps:
(1) move your mouse to query result grid
(2) right click on query result grid
(3) check "Always adjust all column widths"



2017/08/08

[Tools] [Text Compare] How to Compare Two Lengthy JSON String

Problem
I have two lengthy JSON String, if I would like to compare the difference between the two JSON string, how to do it?

How-To
Here are the steps to fulfill this requirement:
(1) connect to https://text-compare.com/
(2) copy first JSON string to left hand side
(3) copy second JSON string to right hand side
(4) click Compare button

(5) check the difference

2017/08/07

[SQL Server] How to find similar table / column name by SQL

I am using Microsoft SQL Server...

If I would like to get a list of table name which table name has %arap%, you can use this SQL statement to do query:
SELECT NAME 
FROM   sys.tables 
WHERE  NAME LIKE '%arap%' 



If I would like to get a list of table which has column name %apply%, you can use this SQL statement to do query:
SELECT t.NAME AS 'TableName', 
       c.NAME AS 'ColumnName' 
FROM   sys.columns c 
       JOIN sys.tables t 
         ON c.object_id = t.object_id 
WHERE  c.NAME LIKE '%apply%' 
ORDER  BY t.NAME, 
          c.NAME; 








2017/08/06

[webMethods] How to Restart / Shutdown / Startup Integration Server

Problem
若我要重新啟動 integration server 的話,該去哪裡執行重啟

How-To
有兩個方式:
(1) 到遠端到安裝 integration server 的機器,到 SoftwareAG 的安裝目錄下,如 [SoftwareAG_HOME]\profiles\IS_default\bin\

執行 restart.bat 表示 restart integration server
執行 shutdown.bat 表示 shutdown integration server
執行 startup.bat 表示 startup integration server

(2) login 到 integration server administration console
點選畫面右上角的 ShutDown and Restart



若要 shutdown integration server,click Shut Down button
若要 restart integration server,click Restart button
若要強制馬上關閉,不管 session 的工作結束與否,點選上方的 immediately radio button



2017/08/05

[webMethods] 如何更新 integration server 的 trial license

Problem
今天當我 log in 到 webMethods integration server 的 administration console 時,出現 trial license 即將 expire 的 warning message


How-To
處理步驟如下:
(1) 到 Software AG [1] download trial license
(2) 將 trial license copy 到安裝 integration server 的特定目錄下
(3) 點選 Edit Licensing Details


(4) 修改 License File 的位置與檔名


(5) restart integration server
(6) login administration console,此時可以發現 warning message 已經消失,expire date 延長到 July 31




Reference
[1] http://www.softwareag.com/Corporate/res/download/default.asp

2017/08/04

[webMethods] Software AG Designer 無法編輯 Document Type, Flow Service

Problem
當我要編輯先前已經開發好的 document type, flow service 時,發現無法進行編輯,相關可編輯的選項都被 disabled



How-To
在欲編輯的 document type 或 flow service 中,按下右鍵,選擇 Lock for Edit



此時你會發現,該 document type 的 icon 出現打勾的符號,編輯的選項也都 enabled 了






2017/08/03

[Lombok] Utilize @Builder annotation to produce complex builder APIs for your classes

Problem
If you would like to apply builder pattern in your Java class, the class will looks like:
package albert.practice.designPattern.builder;

public class User {

    private String firstName;
    private String lastName;
    private String email;

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getEmail() {
        return email;
    }

    private User(UserBuilder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.email = builder.email;
    }

    @Override
    public String toString() {
        return "User [firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]";
    }

    public static class UserBuilder {
        private String firstName;
        private String lastName;
        private String email;

        public UserBuilder firstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public UserBuilder lastName(String lastName) {
            this.lastName = lastName;
            return this;
        }

        public UserBuilder email(String email) {
            this.email = email;
            return this;
        }

        public User build() {
            User user = new User(this);
            return user;
        }
    }
}


Compared with POJO class, you may notice the number of lines of code increase at least to double in builder pattern. Does it has any convenient approach to implement and yield the same benefit which builder pattern bring for us?

How-To
You can make good use of @Builder annotation which provide by Project Lombok. The updated code look like:
package albert.practice.designPattern.builder;

import lombok.Builder;
import lombok.Getter;
import lombok.ToString;

/*
 * The @Builder annotation produces complex builder APIs for your classes.
 * @Builder lets you automatically produce the code required to have your class be instantiable with code such as:
 * Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build();
 */
@Builder
@Getter
@ToString
public class User2 {
    
    private String firstName;
    private String lastName;
    private String email;

}


Here is the test code:
package albert.practice.designPattern.builder;

import static org.junit.Assert.assertNotNull;

import org.junit.Test;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class UserTest {

    @Test
    public void testUser() {
        User user = new User.UserBuilder().firstName("Albert").lastName("Kuo")
                .email("test@gmail.com").build();
        log.debug("user = " + user.toString());
        assertNotNull(user);
    }

    @Test
    public void testUser2() {
        User2 user2 = new User2.User2Builder().firstName("Albert").lastName("Kuo")
                .email("test@gmail.com").build();
        log.debug("user2 = " + user2.toString());
        assertNotNull(user2);
    }

}



Maven dependencies are as bellows:
  <dependencies>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.8</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>

        <!-- logback -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.1.7</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.7</version>
        </dependency>
    </dependencies>

Reference
[1] https://projectlombok.org/features/Builder.html