Posts
>-
條款五十三,避免單獨使用 WHEN OTHERS 去處理例外。
像是下面這樣的程式,使用 WHEN OTHERS 搭配 IF 條件式與 SQLCODE 去處理例外,就是不建議的作法。
... EXCEPTION WHEN OTHERS THEN IF SQLCODE = -1 THEN update_instead (...); ELSE err.log; RAISE; END IF; ... 如果明確使用例外的名稱去處理例外,可以免去不必要的 IF 判斷,及 SQLCODE 的使用。
... EXCEPTION WHEN DUP_VAL_ON_INDEX THEN update_instead (...); WHEN OTHERS THEN err.log; RAISE; ...
read morePosts
Grok patterns
使用 Logstash 免不了會用到 Grok patterns,Grok patterns 其實也就只是用預先定義好的正規表示式來設定怎麼匹配,以及匹配成功後的 Group name,讓設定變得更為簡易、直覺。
Grok patterns 的語法為…
%{SYNTAX:SEMANTIC} SYNTAX 就是預先定義好的正規表示式,SEMANTIC 就是正規表示式匹配後的 Group name,等同於使用下面這樣的正規表示式語法。
(?<<GroupName>><RegexPattern>) SYNTAX 的設定可參閱 logstash/grok-patterns at v1.4.2 · elastic/logstash,參閱設定可更加了解要怎樣使用 SYNTAX,以及有助了解設定的 SYNTAX 為何會無法正確的匹配。
USERNAME [a-zA-Z0-9._-]+ USER %{USERNAME} INT (?:[+-]?(?:[0-9]+)) BASE10NUM (?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+))) NUMBER (?:%{BASE10NUM}) BASE16NUM (?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+)) BASE16FLOAT (?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\.[0-9A-Fa-f]*)?)|(?:\.[0-9A-Fa-f]+))) POSINT (?:[1-9][0-9]*) NONNEGINT (?:[0-9]+) WORD \w+ NOTSPACE \S+ SPACE \s* DATA .*? GREEDYDATA .* QUOTEDSTRING (?>(?<!\)(?>"(?>\.|[^\"]+)+"|""|(?>'(?>\.|[^\']+)+')|''|(?>`(?>\.|[^\`]+)+`)|``)) UUID [A-Fa-f0-9]{8}-(?:[A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12} # Networking MAC (?:%{CISCOMAC}|%{WINDOWSMAC}|%{COMMONMAC}) CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4}) WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2}) COMMONMAC (?
read morePosts
>-
條款五十二,不要使用自定義錯誤去重新定義 Oracle 預先定義的錯誤。
像是下面這樣的程式,使用自定義錯誤重新定義了 no_data_found 錯誤,就是不建議的作法。
DECLARE no_data_found EXCEPTION; … BEGIN ... EXCEPTION WHEN no_data_found THEN sys.dbms_output.put_line(co_no_data_found); END; 比較好的作法應該是反思是否需要重新定義 Oracle 預先定義的錯誤、是否應該定義的是不同的錯誤。
DECLARE empty_value EXCEPTION; ... BEGIN ... EXCEPTION WHEN empty_value THEN sys.dbms_output.put_line(co_empty_value); WHEN no_data_found THEN sys.dbms_output.put_line(co_no_data_found); END;
read morePosts
rush - A cross-platform command-line tool for executing jobs in parallel
rush 是一跨平台的命令列工具,能用來並行指定的命令。
自官網上下載下來後解壓縮即可使用。
其使用方式如下:
rush -- a cross-platform command-line tool for executing jobs in parallel Version: 0.1.9 Author: Wei Shen <shenwei356@gmail.com> Homepage: https://github.com/shenwei356/rush Usage: rush [flags] [command] [args of command...] Examples: 1. simple run, quoting is not necessary $ seq 1 10 | rush echo {} 2. keep order $ seq 1 10 | rush 'echo {}' -k 3. timeout $ seq 1 | rush 'sleep 2; echo {}' -t 1 4.
read morePosts
Redis on Windows
要在 Windows 使用 Redis,可以到這邊下載 Windows 的 Porting 版本。
點擊安裝檔進行安裝。
勾選同意授權。
設定要安裝的位置,這邊也可以勾選順帶設定環境變數。
設定 Redis 要使用的 Port 號,這邊也可以勾選順帶設定防火牆。
設定記憶體使用上限。
安裝完後在指定的安裝位置會看到 Redis 的設定檔,以及 Redis 附帶的一些 CLI Tool,像是 redis-cli、redis-server、redis-benchmark 等。
查看服務也可以看到安裝的 Redis 服務正在背後運行。
更進一步可以使用 Telnet。
或是自帶的 redis-cli 工具進行一下 Redis 的連線測試。
Link MSOpenTech/redis: Redis is an in-memory database that persists on disk. The data model is key-value, but many different kind of values are supported: Strings, Lists, Sets, Sorted Sets, Hashes
read morePosts
>-
條款五十一,不要使用 Error Number 去處理 Unnamed Exceptions。
像是下面這樣的程式,直接使用 Error Number -2291 去處理 Unnamed Exception 就不是建議的作法。
BEGIN ... EXCEPTION WHEN OTHERS THEN IF SQLCODE = -2291 THEN ... END IF; END; 比較好的作法是透過 pragma exception_init 將未命名的內部錯誤做個命名,然後直接用這個命名去攔截對應的錯誤做對應的處理。
DECLARE e_parent_missing EXCEPTION; PRAGMA EXCEPTION_INIT(e_parent_missing,-2291); ... BEGIN ... EXCEPTION WHEN e_parent_missing THEN ... END;
read morePosts
>-
條款五十,避免 hard-codeed FOR loop 的上下邊界值。
像是下面這段程式 hard-coded 了 FOR loop 的上下邊界值,這樣的撰寫預期上下邊界值是不會被變動的,且後續再看這段程式可能也會不理解為何上下邊界值會帶這樣的值,程式的維護性上會比較差。
BEGIN <<for_loop>> FOR i IN 1..5 LOOP sys.dbms_output.put_line(i); END LOOP for_loop; END; 比較好的做法是不要將上下邊界值 hard-coded,可能用常數設定其值,並給予較具意義的常數名稱,讓程式的可讀性與可維護性更好。
DECLARE co_lower_bound CONSTANT SIMPLE_INTEGER := 1; co_upper_bound CONSTANT SIMPLE_INTEGER := 5; BEGIN <<for_loop>> FOR i IN co_lower_bound..co_upper_bound LOOP sys.dbms_output.put_line(i); END LOOP for_loop; END;
read morePosts
PL/SQL SQL CODING GUIDELINE 49 - Avoid use of unreferenced FOR loop indexes
條款四十九,避免未使用的 FOR loop 索引。
像是下面這樣的程式使用了 numeric FOR loop,卻未使用 FOR loop 的索引,導致程式碼變得更為複雜沒有效率。
DECLARE ... BEGIN l_row := co_lower_bound; l_value := co_first_value; <<for_loop>> FOR i IN co_lower_bound .. co_upper_bound LOOP sys.dbms_output.put_line(l_row || co_delimiter || l_value); l_row := l_row + co_row_incr; l_value := l_value + co_value_incr; END LOOP for_loop; END; 比較好的作法是要看看是否能透過索引撰寫出更適合的程式,如果不行則要反思這邊使用 numeric FOR loop 是否合適。
DECLARE ... BEGIN <<for_loop>> FOR i IN co_lower_bound .. co_upper_bound LOOP sys.dbms_output.put_line(i || co_delimiter || to_char(co_first_value + i * co_value_incr)); END LOOP for_loop; END;
read morePosts
MsgPack.Cli - MessagePack implementation for Common Language Infrastructure
MsgPack.Cli 是 MessagePack 在 CLI 下的實作,如果要在 .NET 程式裡面使用 MessagePack,可以直接透過 NuGet 安裝使用。
Install-Package MsgPack.Cli 使用時先引用 MsgPack.Serialization 命名空間,然後透過 SerializationContext.Default.GetSerializer 取得 Serializer,用取得的 Serializer 帶入 stream 與要序列化的物件去調用 Pack 方法即可將物件序列化。
using MsgPack.Serialization; ... public static byte[] Serialize<T>(T thisObj) { var serializer = SerializationContext.Default.GetSerializer<T>(); using (var ms = new MemoryStream()) { serializer.Pack(ms, thisObj); return ms.ToArray(); } } ... 要解序列化則是透過取得的 Serializer 將 Stream 帶入調用 Unpack 方法。
... public static T Deserialize<T>(byte[] bytes) { var serializer = SerializationContext.Default.GetSerializer<T>(); using (var byteStream = new MemoryStream(bytes)) { return serializer.
read morePosts
MessagePack - An efficient binary serialization format
MessagePack 是一個有效率的二進制序列化格式,傳遞的資料內容有點像是 JSON,但是因為是二進制的序列化格式,所以資料量更快且更小。
像是下面這張官網的圖,可以看到 {“compact”:true,“schema”:0} 這樣的 JSON 資料換由 MessagePack 來處理,資料量會從 27 bytes 降到 18 bytes,減少了 67%。
不過官網這張圖只是簡單的示意,實際上 compact 與 schema 這兩個字串得替換為 ascii,所以實際傳送的資料會變為 82 a7 63 6f 6d 70 61 63 74 c3 a6 73 63 68 65 6d 61 00。
若想要讀懂 MessagePack 格式的資料,必需先了解 MessagePack 的 format,其定義如下:
format name first byte (in binary) first byte (in hex) positive fixint 0xxxxxxx 0x00 - 0x7f fixmap 1000xxxx 0x80 - 0x8f fixarray 1001xxxx 0x90 - 0x9f fixstr 101xxxxx 0xa0 - 0xbf nil 11000000 0xc0 (never used) 11000001 0xc1 false 11000010 0xc2 true 11000011 0xc3 bin 8 11000100 0xc4 bin 16 11000101 0xc5 bin 32 11000110 0xc6 ext 8 11000111 0xc7 ext 16 11001000 0xc8 ext 32 11001001 0xc9 float 32 11001010 0xca float 64 11001011 0xcb uint 8 11001100 0xcc uint 16 11001101 0xcd uint 32 11001110 0xce uint 64 11001111 0xcf int 8 11010000 0xd0 int 16 11010001 0xd1 int 32 11010010 0xd2 int 64 11010011 0xd3 fixext 1 11010100 0xd4 fixext 2 11010101 0xd5 fixext 4 11010110 0xd6 fixext 8 11010111 0xd7 fixext 16 11011000 0xd8 str 8 11011001 0xd9 str 16 11011010 0xda str 32 11011011 0xdb array 16 11011100 0xdc array 32 11011101 0xdd map 16 11011110 0xde map 32 11011111 0xdf negative fixint 111xxxxx 0xe0 - 0xff 這邊舉幾個簡單的例子來看。
read more