Total Pageviews

2019/11/15

[Java 8] How to delete files in specific directory?

Requirement
How to delete files in specific directory?

How-To
Here has sample code:
package com.xxx.tool.filegenerator.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

@Slf4j
@Component
public class FileWriter {

    @Value("${file.property}")
    private String propertyFilePath;

    private void deleteFiles() throws IOException {
        Path path = Paths.get(propertyFilePath);

        try (Stream<Path> walk =  Files.walk(path)){
            walk.map(Path::toFile).forEach(File::delete);
            log.debug("delete existing files from {}", path.toAbsolutePath());
        } catch (IOException e) {
            throw new IOException("Fail to delete existing files : " + e.getMessage(), e);
        }
    }

}


2019/11/14

[Oracle] 安裝 Oracel 11g 過程中,發生找不到 wfmlrsvcapp.ear 錯誤

Problem
安裝 Oracel 11g 過程中,發生找不到 wfmlrsvcapp.ear 錯誤

How-To
由於安裝檔被分成 win64_11gR2_database_1of2.zip 與 win64_11gR2_database_2of2.zip,在執行安裝時,會發生此錯誤。

應將 win64_11gR2_database_2of2 目錄下所有檔案,複製到  win64_11gR2_database_1of2 目錄下,再開始安裝,即可避免此錯誤。


2019/11/13

[Microsoft Office] [Word] 如何調整微軟正黑體行距

Problem
因為每個字體有不同的行距,微軟正黑體閱讀起來比較舒服,但預設的行距過大,導致空間的浪費


How-To


2019/11/12

[Apache POI] How to read large excel file

Problem
I am trying to read a large excel file , around 700000 records, via Apache POI.
It takes  lots of time and resources to read this kind of large excel file.
Is it any effective approach to handle this kind of situation?

The original code will take around 60 seconds to read:
package tw.com.abc.dcb.service;

import com.monitorjbl.xlsx.StreamingReader;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.stereotype.Component;
import tw.com.abc.dcb.vo.DcbRecord;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Component
@Slf4j
public class ExcelReaderService {

    /**
     * Read Excel file
     *
     * @param xlsFile excel file path
     * @return excel data
     * @throws IOException fail to read excel file
     */
    public List<DcbRecord> readExcel(String xlsFile) throws IOException {
        List<DcbRecord> result = new ArrayList<>();
        int rowCount = 1;

        try (Workbook workbook = WorkbookFactory.create(new File(xlsFile))) {
            Sheet sheet = workbook.getSheetAt(0);

            Iterator<Row> rowIterator = sheet.iterator();
            while (rowIterator.hasNext()) {
                if (rowCount == 1) {
                    // skip header
                    rowIterator.next();
                    rowCount++;
                } else {
                    Row row = rowIterator.next();

                    DcbRecord record = DcbRecord.builder()
                            .company(row.getCell(0).getStringCellValue().trim())
                            .paymentDescription(row.getCell(1).getStringCellValue().trim())
                            .amount((int) row.getCell(2).getNumericCellValue())
                            .build();

                    result.add(record);
                    rowCount++;
                }
            }
        } catch (IOException e) {
            throw new IOException("fail to read excel file : " + e.getMessage(), e);
        }
        return result;
    }

}



How-To
The original approach to read excel file is not very memory efficient.
We can make good use of Excel Streaming Reader to import this disadvantage.
The new approach's read time will improve to 20 seconds.

Sample code:
package tw.com.abc.dcb.service;

import com.monitorjbl.xlsx.StreamingReader;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.stereotype.Component;
import tw.com.abc.dcb.vo.DcbRecord;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Component
@Slf4j
public class ExcelReaderService {

    /**
     * Read large excel file
     *
     * @param xlsxFile large excel file path
     * @return excel data
     * @throws IOException fail to read excel file
     */
    public List<DcbRecord> readLargeExcel(String xlsxFile) throws IOException {
        List<DcbRecord> result = new ArrayList<>();
        int rowCount = 1;
        try (InputStream is = new FileInputStream(new File(xlsxFile));
             Workbook workbook = StreamingReader.builder().rowCacheSize(100).bufferSize(4096).open(is)) {
            for (Sheet sheet : workbook) {
                for (Row row : sheet) {
                    if (rowCount == 1) {
                        // skip header
                        rowCount++;
                    } else {
                        DcbRecord record = DcbRecord.builder()
                                .company(row.getCell(0).getStringCellValue().trim())
                                .paymentDescription(row.getCell(1).getStringCellValue().trim())
                                .amount((int) row.getCell(2).getNumericCellValue())
                                .build();

                        result.add(record);
                    }
                }
            }
        } catch (IOException e) {
            throw new IOException("fail to read excel file : " + e.getMessage(), e);
        }
        return result;
    }

}




Reference

[1] https://github.com/monitorjbl/excel-streaming-reader

2019/11/11

[Spring Boot] How to create custom repository

Process


1.0 Create Repository  interface
package tw.com.abc.analysis.repository;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import tw.com.abc.analysis.entity.Goal;
import tw.com.abc.analysis.entity.GoalId;
import tw.com.abc.analysis.repository.custom.GoalRepositoryCustom;

import java.util.List;

@Repository
public interface GoalRepository extends CrudRepository<Goal, GoalId> {
}


1.1 Create Repository Custom interface
package tw.com.abc.analysis.repository.custom;

public interface GoalRepositoryCustom {
}



1.2 Create Repository Custom Imple. class
package tw.com.abc.analysis.repository.impl;

public class GoalRepositoryImpl implements GoalRepositoryCustom {
}


1.3 Repository class extends Repository Custom interface
package tw.com.abc.analysis.repository;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import tw.com.abc.analysis.entity.Goal;
import tw.com.abc.analysis.entity.GoalId;
import tw.com.abc.analysis.repository.custom.GoalRepositoryCustom;

import java.util.List;

@Repository
public interface GoalRepository extends CrudRepository<Goal, GoalId>, GoalRepositoryCustom {
}


1.4 Write SQL statement and save in SQL file

1.5 Create Mapper Class
package tw.com.abc.analysis.vo.rowmapper;

import org.springframework.jdbc.core.RowMapper;
import tw.com.abc.analysis.vo.GoalVo;

import java.sql.ResultSet;
import java.sql.SQLException;

public class GoalVoRowMapper implements RowMapper<GoalVo> {

    @Override
    public GoalVo mapRow(ResultSet rs, int rowNum) throws SQLException {
        GoalVo vo = new GoalVo();
        vo.setItemId(rs.getString("itemId"));
        vo.setName(rs.getString("name"));
        vo.setYear(rs.getString("year"));
        vo.setMonth(rs.getString("month"));
        vo.setGoal(rs.getBigDecimal("goal"));
        return vo;
    }
}


1.6 Declare custom method in custom interface
package tw.com.abc.analysis.repository.custom;

import tw.com.abc.analysis.vo.GoalVo;

import java.io.IOException;
import java.util.List;

public interface GoalRepositoryCustom {

    List<GoalVo> findByYear(String year) throws IOException;

}


1.7 Implement custom class method
package tw.com.abc.analysis.repository.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import tw.com.abc.analysis.repository.custom.GoalRepositoryCustom;
import tw.com.abc.analysis.util.SqlFileLoader;
import tw.com.abc.analysis.vo.GoalVo;
import tw.com.abc.analysis.vo.rowmapper.GoalVoRowMapper;

import java.io.IOException;
import java.util.List;

public class GoalRepositoryImpl implements GoalRepositoryCustom {

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Autowired
    private SqlFileLoader sqlFileLoader;

    @Override
    public List<GoalVo> findByYear(String year) throws IOException {
        String sql = sqlFileLoader.getSqlFile("find_by_year.sql");

        MapSqlParameterSource parameters = new MapSqlParameterSource();
        parameters.addValue("year", year);

       return jdbcTemplate.query(sql, parameters, new GoalVoRowMapper());
    }
}





2019/11/10

[Google Sheet] Add-ons : Size My Sheet

Problem
Each Google Sheet can support up to 5 million cells. If I reach its limitation, I cannot keep working on current Google Sheet.

How can I know the usage status in current Google Sheet?

How-To
You can get Size My Sheet add-ons in Google Sheet, then you can get the usage information.

Add-ons => get add-ons


Add-ons => Size My Sheet => Show gauge





2019/11/09

[閱讀筆記] Measure What Matters (5/5)


  1. OKRs 的正確閱讀、解讀與行動

OKRs Type
Reading, Interpreting and Acting
Committed OKRs
  • 團隊預期要重新調整優先順序,確保能夠如期達成且執行分數要能得到 1.0
  • 團隊若確信無法如期或執行結果無法得到 1.0,就需要及時向上反應 (escalate promptly)。這是重點:即時向上反映問題是必要的動作。若問題的來源來自於 OKR 的意見分歧、優先順序的意見分歧、或無法分配足夠的時間 / 人員 / 資源,即時向上反應是好事。此舉能夠讓團隊管理者去發展方案與解決衝突。新的 OKR 勢必會影響團隊的運作,迫使團隊重新調整資源調配;若一個 OKR 不會改變任何團隊的活動,就是一個 business-as-usual OKR
  • 當 committed OKRs 執行失敗,就需要進行事後驗屍 (postmortem)。這並非要懲罰團隊,而是想要了解是規劃或是執行面的問題,讓團隊可以改善能力,在未來能夠如期完成且得到 1.0 的執行結果
  • 例子:本季服務要確保服務水準必須符合預定的 SLA (Service Level Agreement);在某個日期前,交付系統新的功能
Aspirational OKRs
  • Aspirational OKRs 的設計,就是用來超出團隊的能力
  • Aspirational OKRs 與其相關的優先順序,必須持續保留在團隊的 OKR list,直到期完成為止,並且在有必要時,從一個季度待到下個季度。只因為沒有進度就將 OKR list 刪除是錯誤的,這種作法掩飾資源分配的問題,或是 缺乏對問題及解決方案的了解
  • 團隊管理者不應預期要馬上獲得 aspirational OKRs 所需的所有資源,除非他們的 aspirational OKRs 在公司的 committed OKRs 後,擁有最高的優先順序

  1. 更多石蕊測試 (litmus tests),這裡有幾個簡單的測試來看你的 OKRs 是否良好
石蕊測試 (litmus tests)
  • 如果你五分鐘就寫完,通常不會是個好的 OKRs,多想想。
  • 如果你的目標不能一行寫完,那可能不夠清楚明瞭。
  • 如果你的 KRs 表達的是活動 (ex. Launch Foo 4.1),這可能不夠好。重要的不是活動本身,而是活動所造成的影響。例如:Launch Foo 4.1 to improve sign-ups by 25% or improve sign-ups by 25%
  • 使用真實日期。如果每個 key results 都是在每個季度的最後一天完成,這肯定不是一個真實計畫。
  • 確保你的 key results 是可衡量的,例如 improving sign-ups 可能不夠好,更好的描述應是 improve daily sign-ups by 25% by May 1.
  • 確保衡量指標是清楚的。如果你說 1 million users,是指所有時間的用戶,還是七天內活動的用戶。
  • 如果您的團隊中有重要活動未被 OKRs 所涵蓋,請添加更多活動到 OKRs
  • 對於較大的、牽涉多個部門的團隊,讓 OKRs 階層化是必要的,會有一個 high-level OKRs 給整個團隊,每個個別團隊會有夠細節的 OKRs。確保 horizontal OKRs 在每個 subteam 都有在支援 key results

  1. 典型的 OKR Cycle
  2. 持續的績效管理分成兩個部分,兩者是互相緊密結合的流程。第一個部分是設定 OKRs;第二個部分是針對你的需求進行定期、持續的溝通與客製。
目標規劃與反省 (Goal Planning and Reflection)
為了促進溝通,管理者必須問貢獻者 (contributor) 以下問題:
  • 你計畫要聚焦於哪個 OKRs ,藉此帶給你的角色、你的團隊或公司最大的價值?
  • 這個 OKRs 與組織的關鍵活動的方向是否一致?
進度報告 (Progress Updates)
為了鼓勵貢獻者發言,管理者可能要提出這些問題:
  • 你的 OKRs 執行的如何?
  • 有哪些關鍵的能力,是你成功執行 OKRs 必備的?
  • 有沒有哪些事物阻礙你完成目標?
  • 根據優先順序的變化,OKRs 有沒有需要做調整 (增加或移除)?
由主管所引導的培訓 (Manager-led Coaching)
為了準備與員工的對話,主管必須考慮以下問題:
  • 我希望我的報告要繼續展示哪些行為或價值觀?
  • 我希望我的報告要開始或停止展示哪些價值觀或報告?
  • 我可以提供什麼指導,讓貢獻者能充分發揮他或她的潛力?
  • 在對話過程中,領導者應該問
    • 在你的工作中,哪個部分最讓你感到振奮?
    • 如果有的話,在你目前扮演的角色中,有哪個地方是你想改變的?
向上回饋 (Upward Feedback)
為了讓貢獻者坦率地提供意見,管理者必須問以下問題:
  • 從我這邊所得到的協助,你是否感到有幫助?
  • 我是否有阻礙到你的能力發揮與工作效率?
  • 我能夠做什麼,能夠協助你更成功?
職涯成長 (Career Growth)
為了讓貢獻者說出自己的職涯抱負 (career aspirations),管理者或許可以問以下問題:
  • 在你現在的角色,有哪些技巧或能力是你想要發展或改進的?
  • 為了達成你的職涯目標,有哪些領域是你想進一步發展的?
  • 有沒有什麼未來的角色是你想發展的,需要哪些技巧或能力?
  • 從學習、成長與發展的觀點,我與公司如何協助你達成你的職涯成長目標?
準備績效對話 (Prepping for Performance Conversation)
主管在與貢獻者進行績效面談時,有些準備工作需依序進行。領導者特別需要考慮以下事項:
  • 在這段期間,貢獻者主要的目標與責任為何?
  • 貢獻者在此段期間的表現如何?
  • 若貢獻者的表現不如預期,該如何協助其回到正軌?
  • 若貢獻者的表現優良或超乎預期,我如何協助他們維持高檔表現且不會倦怠?
  • 什麼時候是貢獻者最忙碌的時候?
  • 什麼時候是貢獻者最不忙的時候?
  • 貢獻者為工作帶來什麼優勢?
  • 什麼樣的學習經驗對貢獻者可能會帶來好處?
  • 過去六個月,貢獻者應專注於什麼地方?貢獻者在其現有角色是否有符合預期?貢獻者是否在期限有角色發出最大化的貢獻?有沒有替貢獻者準備新的發展機會 - 例如新的專案、更大的責任或新的角色?

貢獻者也需在績效面談前預作準備,可以特別先問問自己以下幾個問題:
  • 我是否有如期完成目標?
  • 我是否有判斷出哪些有機會 / 潛力的領域?
  • 我是否理解我的工作與企業高層較遠大的里程碑之間的關係?
  • 我可以給我主管什麼回饋?

  1. OKR 的四個超能力
Power of OKRs
Description
專注致力優先要務
(Focus and Commit to Priorities)
  • 設定適當的 OKR cycle:我建議雙軌 (dual tracking) 進行,一個是一個季度的 OKR (用於較短期的目標),另一個則是年度的 OKR (用於長期策略)。
  • 強化領導者的承諾,高階主管要努力推動 OKR。
  • 指派 OKR 牧羊人,確保每個人投入在 OKR cycle 的時間,並且是否有選擇最重要的事情在執行
  • 每個 cycle 只會有三到五個最重要的目標。過多的 OKRs 會稀釋與分散你的力氣。提升你效率的方法是,決定哪些事情不要做,將其捨棄或延後在做。
  • 制定企業最高層的 OKRs,包含使命、宣言、策略計畫等
  • 制定部門目標 OKRs 與爭取橫向支持,提升企業的 OKRs
  • 每個目標都要制定不超過五個可衡量、清楚的、有期限的 key results。依照定義,當所有 key results 完成後,目標就達成了
  • 當 key results 需要額外的關注,可將其提升到一到多個 cycles 來完成。
  • OKR 成功最重要的元素是,組織領導者堅定的支持
協調團結促進合作
(Align and Connect for Teamwork)
  • 激勵員工,並展現他們的目標與領導者的院靜、企業的最高優先順序間的關係。
  • 利用全體會議 (all-hands meetings) 向所有員工解釋,為什麼這個 OKR 對組織來說非常重要。
  • 當企業高層訂定 OKRs 後,應當與前線貢獻者高通、交流 key results 的訂定,前線貢獻者 (frontier contributors) 通常會較有創意。
  • 鼓勵由下而上的 OKRs 的訂定,若擁有一半的比例是由下而上訂定的話,會是比較健康的比例。
  • 透過橫向共享的 OKRs 來打破部門間的藩籬。跨功能運作能促進明快且有協調性的決策,這是掌握競爭優勢的基礎。
  • 清楚列出橫向的、跨功能間的依賴關係。
  • 當 OKR 被修改或丟棄時,需要通知所有相關的利害關係人。
追蹤及討論責任歸屬
(Track for Accountability)
  • 從高層以身作則,建立起當責的文化。當領導者能開放地坦承所犯的錯誤,貢獻者就能覺得更開放地冒合理的風險
  • 透過透明、可見的成果衡量標準來激勵貢獻者,少用外在的報酬
  • 指派 OKR 牧羊人 (shepherd),定期了解每個人的執行狀況與進度,將偏離軌道的人導回正軌,或是 fail fast / well
  • 為了維持高績效表現,貢獻者與主管應該每周舉辦一對一的 OKR 會議,加上每個月一次的部門會議
  • 即使 OKR Cycle 已執行一半,OKR 應隨著內外在條件改變,來進行增刪修。目標並非訂了就不能改變,若固執地執行不再相關或無法達成的目標,最後的結果一定是事與願違
  • 當 OKR cycle 結束後,使用 OKR grades 與客觀的自我評價,來評過自我表現,舉辦活動慶祝成果,並規劃與改進一下個 OKR cycle。在進入下一個 OKR cycle 前,花點時間反省上一個 OKR cycle 那些地方有做好、那些地方沒做好。
竭力顛覆創造驚奇
(Stretch for Amazing)
  • 在每個 OKR cycle 開始前,清楚分辨這個目標是必須 100% 要完成的 committed OKR,還是 aspirational OKR  / BHAG (Big, Hairy, Audacious Goals,即巨大、艱難和大膽的目標)
  • 建立一個讓個人不會恐懼失敗、犯錯的環境
  • 激勵員工設定較遠大的目標,來達成更大的成就 (即便有些 BHAG 會無法達到)。但是不要設定那種不切實際的 OKR,當員工知道 OKR 是不可能達成時,會造成團隊士氣低落
  • 為了獲得在產能或創新上,獲得跳躍式的成長,遵照 Google 的 10X 成長的教條 (Gospel of 10X),用 exponential OKR 取代 incremental OKR,這是發生產業破壞與重新發明種類 (category) 的原因。
  • 制定 aspirational OKR 必須符合組織文化,但是最佳的 aspirational OKR 可能會隨著時間一直改變,一切端視下個 OKR cycle 的營運需求
  • 當團隊沒有如期達成 aspirational OKR,若與下個 OKR cycle 仍舊相關,可以考慮放到下個 OKR cycle 繼續執行

  1. 持續的績效管理 (continuous performance management) 的注意事項
    1. 在 issue 變成大問題之前,在員工陷入極度掙扎前,及時給予協助。將年度績效管理變成持續績效管理。
    2. 將 forward-looking OKR 與 backward-looking 年度考核分開,若目標達成率與分紅之間,有緊密關係,會產生風險趨避的行為。
    3. 用透明、以優點為基礎、多維度標準來做績效評核,取代過去的考績排名、stack rankings 的制度。除了分數以外,還要看貢獻者在團隊中扮演的角色、溝通能力與目標設定的抱負等。
    4. 以內在誘因 (如有意義的工作、成長的機會等) 來取代財務誘因,內在誘因的力量更強大。
    5. 為了獲得正面的結果,應實施 CFR (Conversations, Feedback, Recognition) ,透明的 OKR 讓主管的指導更加具體與有效,持續的 CFR 讓員工的每日活動與企業目標緊密結合,保持在正軌
    6. 主管與貢獻者間的績效導向對話 (performance-driven conversation),應允許貢獻者自己定義討論議程。主管的角色是學習與指導。
    7. 透過跨功能 OKR (cross-functional OKR) 來強化團隊間或部門間的關係
    8. 透過同儕認可 (peer recognition) 來強化員工參與與表現。為了強化影響,認可必須是頻繁的、特定的、可視的,與 top-line OKRs 有高度相關
  2. 組織文化的重要性
    1. 讓 Top-line OKR 與組織的使命、願景、價值 (North Star values) 一致
    2. 透過文字來傳達組織文化價值,但是大部分還是要透過你的行為
    3. 透過合作與問責 (accountability) 來促進最佳績效。當 OKRs 是集體的,將關鍵結果指派給個人,並讓他們負起責任。
    4. 使用 OKRs 來促進資訊透明、目標清楚易懂與大局為導向 (big-picture orientation);部署 CFRs 來建立正面、積極、熱誠、延伸思考與每日改進。
    5. 在施行 OKRs 之前,對於文化障礙要有所助益,尤其是當責與信任
  3. 延伸閱讀
作者
書名
Andrew S. Grove
High Output Management
Richard S. Tedlow
Andy Grove: The Life and Times of an America
Michael Malone
The Intel Trinity
Dov Seidman
HOW: Why HOW We Do Anything Means Everything
Sheryl Sandberg
Lean In: Women, Work, and the Will to Lean
Kim Scott
Radical Candor: Be a Kick-Ass Boss Without Losing Your Humanity
Jim Collins
Good to Great: Why Some Companies Make the Leap...And Others Don't
Jim Collins
Great by Choice: Uncertainty, Chaos and Luck - Why Some Thrive Despite Them All
Randy Komisar
Straight Talk for Startups: 100 Insider Rules for Beating the Odds
Eric Schmidt and Jonathan Rosenberg
How Google Works
Laszlo Bock
Work Rules!: Insights from Inside Google That Will Transform How You Live and Lead
Steven Levy
In The Plex: How Google Thinks, Works, and Shapes Our Lives
Christina Wodtke
Radical Focus: Achieving Your Most Important Goals with Objectives and Key Results

  1. 本書論述結構