2017/07/30

遠離惡男

在不想動腦子,又不想太頹廢的颱風天,當然就是找本雜書來讀了
挑了一本遠離惡男好了,看看女性同胞會想避開的男生有怎樣的特質
「遠離惡男」的圖片搜尋結果

先說說看完的想法

  • 媒體常常報導恐怖情人的新聞,有時我一直覺得為什麼那些人會不知要避開這些恐怖人格特質。後來才了解,有蠻多人是不知道要避開怎樣的特質來保護自己,也有些特質心機頗深,等覺醒時已經陷入了。這本書點出一些特質,蠻值得大家先了解一下,提早防範
  • 用A-Z的方式來歸類惡男是蠻有趣的方式,不過有些項目的人格特質是具有重複性,而且有些特質我想還不至於算是惡男。倒覺得可以針對這26個項目加上嚴重性的評等,這樣會更有客觀性一些
  • 我想不止女生值得讀,男生也值得一讀。一方面檢視自己是不是書中說的惡男外,一方面也要防範惡女,畢竟性別平等的時代,惡情人是不分男女的
  • 如果換個角度看這本書,也會發現裡面的內容蠻受用的,例如在找合作夥伴時,也可以拿來檢視夥伴有沒有這樣的特質,如果有可以提早防範

留一下我的筆記
(特質是摻雜了我的想法,不一定完全與此書相同;嚴重性是純屬我個人意見)
類別特質嚴重性
Angry -- 易怒的情緒化、易動怒、無法控制自我之行為與言語★★★★★
Bedraggled -- 骯髒邋遢的髒亂、粗心、得過且過、無責任感
未把對方放在心上
★★
Control -- 善於控制的自我、霸道、我行我素、有控制慾、不尊重他人個體或想法★★★★★
Disdaiuful -- 輕蔑的自命不凡、狗眼看人低、以否定他人為樂
強將自己的價值觀灌注到別人身上
★★★
Exaggerate -- 浮誇不實的表裡言行不一、打腫臉充胖子★★★★
Festidious -- 喜愛挑剔的缺乏成就或能力、以挑剔別人來掩飾自己的無能或自卑★★★
Gamble -- 好賭的做事與思想投機、賭注超過自己能力 (到處借)★★★★★
Hangover -- 宿醉的酒鬼、以外物來麻醉自我(酒、毒...)、玩物喪志★★★★★
Impose -- 善於欺騙的嘴甜、口才好、但缺乏真心★★★★
Justification -- 好爭辯的執著、堅持己見、以邏輯與話術來包裝定見、不易接受他人的想法★★★
Knit -- 善於編織美夢有夢最美,卻不思踏實、光說不練★★★
Leech -- 水蛭從獵物身上擷取資源直到榨(詐)乾為止、不想自己成就自己★★★★★
Mama -- 媽媽媽寶、缺乏自我主張★★★
Neurosis -- 神經病神經質、愛恨強烈、可以瘋狂到忽略所有法律與道德規範★★★★★
Opaque -- 不透明的不願公開與伴侶的關係、不願他人摸清他個人與行蹤、沒有說謊但也不坦白★★★★
Pedant -- 學究賣弄學問(人脈、資源...)、事後諸葛★★★
Quarantine -- 孤立的習慣孤立、與他人疏離,也會將之傳染給身邊的人★★★★
Resentment -- 憤怒的憤世嫉俗、怨天尤人、千錯萬錯都不是他的錯★★★★
Selfish -- 自私的只在乎自己的需要,別人只是滿足自己的工具★★★
Twofold --雙面的在你面前與背後表現不一
很有心機的在背後破壞聲譽與形象,切斷可能之後援與關懷,讓你無法停止對他的依賴
★★★★★
Undutiful -- 不忠的沒有忠誠、缺乏責任★★★
Vanish -- 慣於消失的不告而別、消失無蹤、無法聯絡★★★
World-wide -- 屬於全世界的風雲人物、屬於全世界,不是你能獨享
Xerox -- 複印的像前男友
老是找同樣類型的伴侶,這是自己本身的問題
Yes -- 沒有主見的不願做決定★★
Zero -- 沒有結果的難有結局的一場情感 (第三者、不倫戀、單戀...)★★★



2016/09/18

Uncaught ReferenceError: $ is not defined

I got a weird error when debugging my web page on Chrome. The Developer Tool shows a "Uncaught ReferenceError: $ is not defined". And the error is in getPageLang function.
I checked my code and grep on my whole project, I could't find  the codes in my project. It is very weird!

After hours study, I got the exception is from Skype extension of Chrome. If you disable the Skype extension, the error won't happen.

Great! It is not my problem!
And hope this can help you if you also encounter this ERROR!

2016/07/27

iBatis遇到Postgresql的JSON/JSONB type

Postgresql等資料庫在較新的版本中,都提供了JSON/JSONB這樣的data type,這提供了開發者更動態的便利性。關於JSON/JSONB可以參考這裡,本文就不贅述。

如果是使用iBatis來做ORM,又該如何與JSON做mapping呢
這裡記錄一下我的試做

我的table結構是
CREATE TABLE public.test
(
  oid bigint NOT NULL,
  data text,
  jdata1 json,
  jdata2 jsonb,
  CONSTRAINT "PK_TEST" PRIMARY KEY (oid)
)


Java class是
public class CTest {
private long oid;
private String data;
private String jdata1;
private String jdata2;
  // getter/setter略
}

則我們可以用下列的iBatis mapper XML
<resultMap id="test" type="CTest">
<result property="oid" column="oid"/>
<result property="data" column="data"/>
<result property="jdata1" column="jdata1"/>
<result property="jdata2" column="jdata2"/>
</resultMap>
<insert id="newTest" parameterType="Map" statementType="PREPARED">
insert into test (oid, data, jdata1, jdata2)
values (#{oid}, #{data}, cast(#{jdata1} as json), cast(#{jdata2} as jsonb));
</insert>
<select id="getTest" resultMap="test" parameterType="Map" statementType="PREPARED">
select * from test where oid=#{oid};
</select>


這樣就可以用下列的iBatis mapper程式來存取table了
public void newTest() throws Exception {
JSONObject o1 = new JSONObject();
o1.put("name", "Yoyo Chen");
o1.put("age", 25);
o1.put("qualified", true);
Map map = new HashMap();
map.put("oid", 333);
map.put("data", o1.toJSONString());
map.put("jdata1", o1.toJSONString());
map.put("jdata2", o1.toJSONString());
execute("newTest", map);
}

public CTest getTest(long oid) {
Map map = new HashMap();
map.put("oid", oid);
CTest t = (CTest) selectOne("getTest", map);
return t;
}


ps. execute()與selectOne()是我的methods,主要是包裝了iBatis的methods

2016/06/07

Socket Options

開發網路程式的朋友都應該用過socket,而socket中除了基本的方法與屬性外,還有不少options。如果觀察Socket的JavaDoc,你一定會發現有很多關於SO_XXXX、IP_XXXX、TCP_XXXX之類的屬性。這些屬性多半與通訊的連線成功或傳輸關係不是那麼大。但是,如果程式需要關注到效能,那這些屬性就會扮演重要的角色。

從Java的角度來檢視一下這些options:


IP_TOS


TOS(Type-Of-Service)的值必須介於[0..255]間。RFC 1394中則定義了下列

  • 0x00 -- normal service
  • 0x02 -- minimize monetary cost
  • 0x04 -- maximize reliability
  • 0x08 -- maximize thrughput
  • 0x10 -- minimize delay

程式可依需要將這些值做bitwise運算,來設定通訊時的等級(例如0x14是指minimize delay and maximize reliability)。
不過並不是所有的設備都會依照這個option的設定來進行傳輸,但是有需要還是可以設上。

SO_LINGER

linger是拖延的意思,這會影響Socket.close()的速度。
如果觀察TCP State Diagram,當我們做close socket的動作時,連線兩端還是會做許多複雜的動作。其中active close這端在TIME_WAIT會等待 2*MSL (Maximum Segment Lifetime)的時間,來確保送出的資料可以被另一端接收到。在RFC 793中提到了MSL是120秒。不同的OS與應用會去調整這個值,目前多數的Linux、BSD及Windows是30秒。

對於寫server-side程式的人來說,linger時間太長,你的程式雖然已經close這個socket了,但是在底層並沒有真的關掉,還在TIME_WAIT的狀態,造成了程式在短時間內沒有辦法再bind到這個port。
現在的internet速度與穩定性已經比早年好太多了,應該不需要這麼長的linger time了。如果你的程式需要較多的socket開關操作時,可以考慮把linger time設小一點。

如果把linger time設為0呢?則程式會送出設有RST flag的封包給對方,可以達到快速結束連線的效果。但是,對方的程式可能會發生 "Connection reset by peer" 的錯誤。

SO_TIMEOUT

這個時間是Socket.getInputStream().read()會被block的等待時間長度。如果read等待超過這個時間長度,則會丟出java.net.SocketTimeoutException。
SO_TIMEOUT的值須大於0,若為0,則視為無止盡。
這個值設太小,就容易常發生timeout的現象;若設太大,有時程式又會被block太久,反應速度變長。所以如何拿捏就要看應用類型而定了。

SO_SNDBUF / SO_RCVBUF

對底層的傳送/接收緩衝區大小的建議值。
這只是建議值,底層會依照所設定的值,在參照實際系統狀況來決定這兩個緩衝區的大小。
前輩建議,如果是在通訊較不好的環境,或是瞬間傳送的速度很快,那SO_SNDBUF可以設大些,這樣可以確保TCP sliding window夠大,足以容納一值無法成功送出的資料。
如果是電腦的處理速度慢,那SO_RCVBUF就要設大些,免得來不及處理,資料掉了。

SO_KEEPALIVE

如果socket建立了,但是長時間(2小時,視OS實作而定)沒有進行資料傳送,這個連線很可能會被中間的某個網路設備中止。為了避免這情形發生,如果啟用了SO_KEEPALIVE,則socket會自動發出一個keepalive probe給對方,對方也會回應回來,讓網路設備知道這個連線仍在使用中。
對有些應用或環境來說,2小時真的太長了(尤其是行動網路,有些系統商大概不會讓你站用連線這麼久),而且對Java也無法變更改時間值,所以許多應用就會自己實作ping/pong的機制來當作keep-alive。

SO_OOBINLINE

當連線有許多資料排隊要送時,如果有一緊急事件要插隊通知對方,就可以用 OOB (Out-Of-Band) Inline。啟用SO_OOBINLINE,並可透過Socket.sendUrgentData來即時送出 1-byte的資料給對方。
不過,直到Java 8,都沒有看到可以接收urgent data的方法。所以...

TCP_NODELAY

在提這項之前,要先瞭解Nagle's algorithm。簡單的說,想想一家貨運公司,如果一收到小貨物就馬上出車送貨,對公司來說整個營運效能就不高,對整個道路來說就會增加車次,容易造成路上塞車。
若是貨運公司將這些收到的小貨物累積到一定的量才出車送貨,那公司的營運效能才能提高,不會造成浪費。但是這就會造成最前面的幾件貨物要等很久才會被送出。
TCP_NODELAY就是停用Nagle's algorithm,來提高throughput。
如果所開發的系統常會傳送小資料,這個選項就該納入考慮。


以上做為工作上的紀錄,方便未來查閱。也希望對大家都有些幫助。

2016/05/05

JavaMail透過GMail送信遇到的問題

這樣的技術文件,網路上應該很多了,那些詳細的實作就不贅述
套著網路上的資訊,使用了下面的參數


結果遇到了下列的exception

javax.mail.MessagingException: Can't send command to SMTP host;
  nested exception is:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:1564)
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:1551)
at com.sun.mail.smtp.SMTPTransport.ehlo(SMTPTransport.java:935)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:426)
at javax.mail.Service.connect(Service.java:310)
at javax.mail.Service.connect(Service.java:169)
at javax.mail.Service.connect(Service.java:118)
at com.ruby.vtun.entity.GeneralMail.send(GeneralMail.java:133)
at com.ruby.vtun.entity.GeneralMail.main(GeneralMail.java:161)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1439)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:209)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:878)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:814)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
at com.sun.mail.util.TraceOutputStream.write(TraceOutputStream.java:114)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:1562)
... 8 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1421)
... 19 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
... 25 more


經過被蹂躪了一陣子,總算發現是我的防毒軟體Avast作怪!把Avast關掉,就可以正常送信了。
要解決這問題,除了關掉Avast外,可以透過更改Avast的設定來解決,因為目前是使用port 587來送,只要把587從Avast的設定中拿掉,就可以正常送信了