<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/rss.xsl" type="text/xsl"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><generator>Typlog 3.1 (https://typlog.com)</generator><title><![CDATA[Chen ZiQiang's Blog]]></title><description><![CDATA[Hello, my name is Chen ZiQiang. Welcome to my blog, where I share my life experiences and thoughts.]]></description><link>https://czq.me/</link><copyright><![CDATA[Copyright 2026 Chen ZiQiang's Blog]]></copyright><image><url>https://i.typlog.com/czqone/8230991847_584123.png?x-oss-process=style/sl</url><title><![CDATA[Chen ZiQiang's Blog]]></title><link>https://czq.me/</link></image><atom:link href="https://czq.me/feed.xml" rel="self" type="application/rss+xml"/><atom:link href="https://pubsubhubbub.appspot.com/" rel="hub"/><pubDate>Thu, 16 Apr 2026 12:14:00 +0000</pubDate><item><title><![CDATA[懐かしのバブル時代]]></title><guid>https://czq.me/posts/huai-kashinobaburushi-dai-c53f9797</guid><link>https://czq.me/posts/huai-kashinobaburushi-dai-c53f9797</link><pubDate>Sat, 07 Mar 2026 05:57:00 +0000</pubDate><content:encoded><![CDATA[<p>バブル時代の歌はとても個性がはっきりしています、今のJpopと雰囲気は全然違います、バブル時代の歌は明るくて、未来にワクワクする。</p>
<p>３０代の私にとっても、どこか懐かしくて憧れます。</p>
<p><a href="https://www.youtube.com/watch?v=42yiDEEWQnQ">Won't Be Long -The Bubble Gum Brothers</a></p>
<p><a href="https://www.youtube.com/watch?v=_3gi46xH6XM">赤道小町ドキッ／山下久美子</a></p>
]]></content:encoded></item><item><title><![CDATA[「一橋桐子の犯罪日記」についての感想と終活の話]]></title><guid>https://czq.me/posts/yi-qiao-tong-zi-nofan-zui-ri-ji-nitsuitenogan-x-c409b335</guid><link>https://czq.me/posts/yi-qiao-tong-zi-nofan-zui-ri-ji-nitsuitenogan-x-c409b335</link><pubDate>Thu, 19 Feb 2026 14:06:57 +0000</pubDate><content:encoded><![CDATA[<h2>感想</h2>
<p>最近SSJの読書部で終活応援の本「一橋桐子の犯罪日記」を読みました。</p>
<p>桐子さんの老後生活の辛いさを感じました、お金の問題とか、人との関係とか、親の介護とか、部屋を借りるなら保証会社も難しくそうです、年を増えていくかクビになるかも知れません、いつか騙されるの詐欺もあります。</p>
<p>こういうらの問題を改善なら、国と社会からいろいろな手伝わなければならないです。日本とか低収入向けの給付金とか、いろんなNPOからの無料食料の配るとか、歳を取った人向けの部屋賃貸優待とか、これらの政策があれば、刑務所に入りたい人の気持ちが減っているかなと思います。これらの人たちももいい終活になるかも知れません。</p>
<h2>終活</h2>
<p>終活というのは自分の死に備えることです、他人に迷惑をかけないためようです。</p>
<p>初めて聴く時、驚きました、自分の死まで他の人に迷惑をかけないように、まさか日本人がすげーと思いました。</p>
<p>前の日本語学校での６０代の林先生は終活もう始まりましたと言われる時、びっくりしました。８０歳の時を始まるかなと思います、日本の平均年齢は８０何歳ですから。でも僕はその歳になったら、考えは変わるかも知れませんです。</p>
<p>中国であまりそいう議論がないかな、まだ日本の高齢化ようになっていないのためと思います、詳しくわからないですけど、僕の爺さんは九十歳ですけど、まだ自分でお金を管理している、耳と目も悪くて、銀行の手帳の字も見えないぐらいでも、自分で管理しています。</p>
<p>中国の高齢化進めていく、終活もどんどん広がっていくかも知れないです。</p>
<p>時々考えて、もし自分は何が事件が囲まれて、亡くなって、自分の財産とかはどうやって親に渡すか、まあ〜、難しいかな、パスワードとかさ、もっといい方法考え必要かも。</p>
]]></content:encoded></item><item><title><![CDATA[2025年の振り返りと2026年のゴール]]></title><guid>https://czq.me/posts/2025nian-nozhen-rifan-rito2026nian-nogoru-9ea289c0</guid><link>https://czq.me/posts/2025nian-nozhen-rifan-rito2026nian-nogoru-9ea289c0</link><pubDate>Wed, 11 Feb 2026 13:57:25 +0000</pubDate><content:encoded><![CDATA[<p>日本に３年目でした、少し慣れていましたけれども、今後の人生を考えて、もっと変えたいです、もっと自由の生活に頑張りたいです。</p>
<h2>2025年の振り返り</h2>
<p>一年間で目標なく、ただの普通の好きではない仕事をやっていました。</p>
<p>毎月必ずどこで遊びに行きます、イベントとか山とか海とか、遊びは楽しかったです。</p>
<p>ITエンジニアに関することはあまり勉強していない、AIのプログラミングはめっちゃ発達しています、いつかクビになるかも知れません。未来はどうなエンジニアが必要ですがもっと考えしないと、もしかしてみんなプログラミングができる、一人会社を作るかも知れません。</p>
<p>日本語のレベルあまり変わっていないかな。日本人の友達になるのは難しいと思います、時時林先生の居酒屋に行って、楽しいで日本語を喋ります、よく政治とか音楽の話をしています。</p>
<p>５月の時、フルテレワークの仕事から出勤する仕事になりました。</p>
<p>６月の時、副業として、二つことを試しました。</p>
<p>一つ目はAIを使ってショットビデオを作って、Youtubeに発信する、効果がありましたが、ショットビデオを作るのは大変だったです、初めの時は二、三時間で一本しか出さないです、そして自分はそれについての趣味はあまりないです、まだ二つ目のことに一緒にやっています、夜遅く朝二時ぐらい寝る、それでとまりました、いつか他の副業できないならば、もう一度試してみます。</p>
<p>二つ目Claude Codeを使って幾つのサイトを作りました、あまり効果が出なかったです。宣伝することが大事と言われましたが全然やっていない、これから宣伝のことしかり勉強しなければならないです。
今も役に立つのサイトを作っています、ほとんどAIで作ります、自分はリーダーような感じになりました、技術だけだはなく、どんな機能を持っているのはいいか、AIと交流して、決めます。</p>
<p>今年二回目実家に帰りました、親に世話することも大事です。</p>
<p>年末の新聞で日本の国籍法の帰化要件は日本に住んでいる５年から１０年に変えるつもりはずです、これからももっと考えが必要です。</p>
<p>多分唯一達成感のことは、今年五回目献血行きました、三年間で総献血数は十五回になりました。</p>
<h2>2026年のゴール</h2>
<p>32歳になりました、なんか緊張感がありました、社会と親からのプレッシャーの原因かな、それでなんの成果もない。技術もそう何うまくではない、日本語も中途半端です、全然うまくないです、英語はももっと悪いです。</p>
<p>よく考えています、自分として生き延びるはなんですか、これは大きな課題ようです、まだはっきり言うことができませんが、自由は一番の目標として頑張りたいです。</p>
<p>今年のゴールは以下になります。</p>
<ol>
<li>体の健康、健康はすべての基礎、これは特に力を入れたいです。</li>
<li>睡眠。毎週5日、８時間の睡眠を確保する。</li>
<li>運動。毎週3回以上、ジョギングをする。</li>
<li>飲食。高糖・高脂肪の飲食を控えたい、週2回までにする。</li>
<li>本業以外の収入の多様化、今年主にSaasを中心とした副業の立ち上げたいです、一円でもいいので、そいうフライホイールを作りたいです。（毎週６時間）</li>
<li>趣味関する分野と言語を勉強する。（毎週４時間時間）</li>
</ol>
<p>これからはもっと詳しくプランを展開します。</p>
<p>以上になります、これからの人生はもっと自分らしいになりたいと頑張っていきたいと思います。</p>
]]></content:encoded></item><item><title><![CDATA[SSJメンバーイベントの話]]></title><guid>https://czq.me/posts/ssjmenbaibentonohua-1d00898e</guid><link>https://czq.me/posts/ssjmenbaibentonohua-1d00898e</link><pubDate>Sun, 25 Jan 2026 13:30:37 +0000</pubDate><content:encoded><![CDATA[<h2>① 最近楽しかったこと</h2>
<p>昨日は千葉県の稲毛（いなげ）海浜（かいひん）公園に行きました。
めっちゃ綺麗な夕方（ゆうがた）を見ました。</p>
<h2>② 今年やりたいこと・行きたいところ</h2>
<p>神奈川県（かながわけん）の丹沢山（たんざわさん）を上り行きたいです。
立派な富士山を見えはずです。</p>
<h2>③ もし1か月休みがあったら？</h2>
<p>四国遍路（しこくへんろ）に歩きたいです。
八十八ヶ所のお寺があって、面白いそうです。</p>
<h2>④ 最近ハマっているもの</h2>
<p>カメラかな、登山の途中で素敵な風景を撮りたいです。</p>
<h2>⑤ 1年前の今ごろ、何をしていましたか？</h2>
<p>実家にテレワークの仕事をしていまし、一ヶ月ぐらいで滞在しました。</p>
<h2>⑥ 最近撮った写真を見せてください</h2>
<p>昨日の稲毛（いなげ）海浜（かいひん）公園です。</p>
<div class="gallery"><div class="gallery_column"><figure><picture><source srcset="https://i.typlog.com/czqone/8230565362_486396.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230565362_486396.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_486396.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230565362_486396.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230565362_486396.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230565362_486396.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_486396.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230565362_486396.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230565362_486396.jpg" alt="P1240626.jpg"loading="lazy" decoding="async" width="5184" height="3888" /></picture></figure><figure><picture><source srcset="https://i.typlog.com/czqone/8230565362_47662.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230565362_47662.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_47662.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230565362_47662.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230565362_47662.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230565362_47662.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_47662.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230565362_47662.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230565362_47662.jpg" alt="P1240643.jpg"loading="lazy" decoding="async" width="5184" height="3888" /></picture></figure><figure><picture><source srcset="https://i.typlog.com/czqone/8230565362_48154.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230565362_48154.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_48154.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230565362_48154.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230565362_48154.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230565362_48154.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_48154.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230565362_48154.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230565362_48154.jpg" alt="P1240758.jpg"loading="lazy" decoding="async" width="5184" height="3888" /></picture></figure><figure><picture><source srcset="https://i.typlog.com/czqone/8230565362_481162.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230565362_481162.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_481162.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230565362_481162.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230565362_481162.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230565362_481162.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_481162.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230565362_481162.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230565362_481162.jpg" alt="P1240799.jpg"loading="lazy" decoding="async" width="5184" height="3888" /></picture></figure></div><div class="gallery_column"><figure><picture><source srcset="https://i.typlog.com/czqone/8230565362_478754.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230565362_478754.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_478754.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230565362_478754.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230565362_478754.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230565362_478754.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_478754.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230565362_478754.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230565362_478754.jpg" alt="P1240851.jpg"loading="lazy" decoding="async" width="5184" height="3888" /></picture></figure><figure><picture><source srcset="https://i.typlog.com/czqone/8230565362_478358.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230565362_478358.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_478358.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230565362_478358.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230565362_478358.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230565362_478358.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_478358.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230565362_478358.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230565362_478358.jpg" alt="P1240874.jpg"loading="lazy" decoding="async" width="5184" height="3888" /></picture></figure><figure><picture><source srcset="https://i.typlog.com/czqone/8230565362_316056.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230565362_316056.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_316056.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230565362_316056.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230565362_316056.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230565362_316056.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230565362_316056.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230565362_316056.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230565362_316056.jpg" alt="P1240895.jpg"loading="lazy" decoding="async" width="5184" height="3888" /></picture></figure></div></div>
<h2>⑦ 最近ちょっと困ったこと</h2>
<p>日本の国籍法は変わるかも、帰化の条件は５年から１０年に変えるそうです。日本来る前に帰化する準備があって、この状況で厳しいに考えられます。</p>
]]></content:encoded></item><item><title><![CDATA[中日文化差异之公司内的称呼]]></title><guid>https://czq.me/posts/zhong-ri-wen-hua-chai-yi-zhi-gong-si-nei-cheng-h-4ce73b4a</guid><link>https://czq.me/posts/zhong-ri-wen-hua-chai-yi-zhi-gong-si-nei-cheng-h-4ce73b4a</link><pubDate>Fri, 23 Jan 2026 13:57:57 +0000</pubDate><content:encoded><![CDATA[<p>在中日公司内，大家互相的称呼不太一样。</p>
<p>在中国大家倾向于省略姓直接叫名字的部分，也有从姓名中取出一个字加上哥or姐。
在日本大家都是姓加上桑。
比如我的名字，在中国大家叫我，自强or强哥，在日本大家叫我陈桑。</p>
<p>在中国大家似乎习惯于通过称呼去拉近关系，有时候会聊聊私事，这样似乎好办事。在日本大家都是按照规则工作，个人之间保持距离，几乎不会聊私事。</p>
<p>我个人觉得两者互有优缺点，可能更倾向于前者，那也是我习惯的一种工作生活方式。</p>
]]></content:encoded></item><item><title><![CDATA[【スピーチ】大人になって気づいたこと]]></title><guid>https://czq.me/posts/supichi-da-ren-ninatsuteqi-duitakoto-11a3a97d</guid><link>https://czq.me/posts/supichi-da-ren-ninatsuteqi-duitakoto-11a3a97d</link><pubDate>Sun, 18 Jan 2026 10:30:00 +0000</pubDate><content:encoded><![CDATA[<p>初めこのテイマを見ると、椎名林檎の<a href="https://www.uta-net.com/song/241087/">人生は夢だらけ</a>という歌を思いました、その中に「大人になって」という歌詞があります。</p>
<p>大人になって気づいたこと、こちら三点を話したいです。</p>
<h2>一点目、自分の人生、自分の責任</h2>
<p>自分の人生の決定はどんな結果があても自分で責任を持ったなければならない。
それで、決まる前に一番悪い結果を想像して、その結果は受けることができるかどうか考えて決めます。</p>
<h2>二点目、資産運用</h2>
<p>資産運用（うんよう）は大事、最近の日本でも物価上昇（じょうしょう）しています、それに対してNISAとか、iDeCoとか、活用して負担を少し減っていくじゃないかなと思います。</p>
<h2>三点目、政治</h2>
<p>政治も大事、多分みんな知っている、中国では政治に関心することができません、でも、政治は自分の周りに多くことが繋がっている、例えば、歳をとった人に対するの高齢化政策とか。</p>
<p>以上になります。</p>
]]></content:encoded></item><item><title><![CDATA[Rubyの世界でパッケージ管理は二つツールになる原因]]></title><guid>https://czq.me/posts/ruby-world-package-manage-is-two-tools</guid><link>https://czq.me/posts/ruby-world-package-manage-is-two-tools</link><pubDate>Wed, 31 Jul 2024 14:57:09 +0000</pubDate><content:encoded><![CDATA[<p>パッケージ管理について、Node.jsとかGolangとか、Rustとか、一つツールで管理できる。</p>
<p>でもRubyはパッケージのインストール（gem）とパッケージの依存関係管理（bundle）、二つツールになりました。</p>
<p>初めてRubyを学びのとき、疑問がありました、どしてRubyは二つツールでパッケージ管理するか、一ついいじゃないか。</p>
<p>それで、最近もっと気になりました、調べました、ようやくわかりました。簡単に言うと、歴史の原因です、Rubyも古い言語になりました、Javaと同じ時代だ。</p>
<h2>原因</h2>
<p>２００３年RubyGemsは一つパッケージのインストール上手くできるために作られました。プロジェクトのパッケージの依存関係管理の要望がないでした。</p>
<p>その後、gemを使いどんどん増えると、gemバージョンコンフリクト(version conflict)の問題が厳しになりました。</p>
<p>２００９年Bundlerはパッケージの依存関係管理のために作られました。</p>
<p>その原因で、Rubyはパッケージ管理で二つツールになりました。</p>
<h2>現状</h2>
<p>今は、RubyGemsとBundlerは同じ<a href="https://github.com/rubygems/rubygems">プロジェクト</a>にマージになりましたけど、まだ別々のコマンドの状態です。</p>
<h2>参考</h2>
<p><a href="https://www.youtube.com/watch?v=4DqzaqeeMgY"> RubyConf 2015 - How does Bundler work, anyway? by Andre Arko </a></p>
]]></content:encoded></item><item><title><![CDATA[日本の大道芸面白い、好きな芸人を紹介]]></title><guid>https://czq.me/posts/daidougei-sukina-geininn-kanou</guid><link>https://czq.me/posts/daidougei-sukina-geininn-kanou</link><pubDate>Sun, 12 May 2024 14:03:43 +0000</pubDate><content:encoded><![CDATA[<p>先月高円寺びっくり大道芸２０２４に行きました、たくさん面白い芸人を見ました。好きな芸人を紹介します。</p>
<h2>加納真実</h2>
<p>いつも青いジャージや白い靴を着ます、観客とインタラクティブ力が強いの加納真実さんです。</p>
<p>最近もYoutubeでたくさん前の作品を見ました。</p>
<p>一番人気の作品は「仮面舞踏会」、歌舞伎ような白いマスクを着て、たくさんの人と一緒に踊ります、みんな盛り上げますね。</p>
<p>初め見ると、「やー、これは日本っぽいですね」、日本だけで見えます、という感想がでました。</p>
<h3>好きの点</h3>
<p>一、作品は日本古い音楽を使って、聴いてないですけど、懐かしの感覚があります。</p>
<p>二、観客も作品を参加することができます。みんなと一緒に、やはり一番魅力です。</p>
<p>それで、作品の面白さは観客によって違います、同じ作品見っても、面白いものがあります。</p>
<h3>仮面舞踏会（高円寺びっくり大道芸２０２４）</h3>
<p><a href="https://www.youtube.com/shorts/axBqJwGMOJ8">短ビデオを撮影しました</a></p>
<p><a href="https://www.youtube.com/watch?v=9Wx7-ljzbbQ">別の人の撮影、同じ回の作品</a></p>
]]></content:encoded></item><item><title><![CDATA[在 Ruby 中如何创建不转义的多行字符串]]></title><guid>https://czq.me/posts/zai-ruby-zhong-ru-he-chuang-jian-bu-zhuan-yi-de-29998513</guid><link>https://czq.me/posts/zai-ruby-zhong-ru-he-chuang-jian-bu-zhuan-yi-de-29998513</link><pubDate>Tue, 16 Apr 2024 07:47:18 +0000</pubDate><content:encoded><![CDATA[<p>今天遇到的字符串转义问题，开始的路走错了，总想把转义后的字符串解析成不转义的字符串。理论应该也可以做到，应该要看到字符串内部任何解析的了。</p>
<h2>问题</h2>
<p>在解决 <a href="https://adventofcode.com/2015/day/8">这个问题</a> 的时候，我需要计算字符串在没有转义之前的长度。</p>
<p>因为我要解析的文本是一个多行的字符串，所以我打算在运行时把转义后的字符串解析成非转义的字符串。</p>
<p>但是似乎很难做到，即使替换反斜杠 \ 到 \ 也没有作用。想想还是要在输入的就写成不转义的字符串。</p>
<p>我们知道在 Ruby 中，不转义字符串使用单引号来创建。</p>
<div class="block-code" data-language="rb"><div class="highlight"><pre><span></span><code><div class="line"><span class="nb">puts</span> <span class="s1">&#39;</span><span class="se">\x27</span><span class="s1">&#39;</span>
</div><div class="line"><span class="c1"># \x27</span>
</div></code></pre></div>
</div>
<p>但是多行如何创建呢。</p>
<h2>Heredoc 多行字符串</h2>
<div class="block-code" data-language="rb"><div class="highlight"><pre><span></span><code><div class="line"><span class="n">example</span> <span class="o">=</span> <span class="o">&lt;&lt;~</span><span class="sh">&#39;</span><span class="dl">END</span><span class="sh">&#39;</span>
</div><div class="line"><span class="sh">    &quot;&quot;</span>
</div><div class="line"><span class="sh">    &quot;abc&quot;</span>
</div><div class="line"><span class="sh">    &quot;aaa\&quot;aaa&quot;</span>
</div><div class="line"><span class="sh">    &quot;\x27&quot;</span>
</div><div class="line"><span class="dl">END</span>
</div></code></pre></div>
</div>
<p>通过给 Heredoc 块的标识加上单引号即可以转变为不转义的字符串。</p>
<p><a href="https://ruby-doc.org/core-2.5.0/doc/syntax/literals_rdoc.html#label-Here+Documents">参考文档</a></p>
<h2>文件读取</h2>
<div class="block-code" data-language="rb"><div class="highlight"><pre><span></span><code><div class="line"><span class="no">File</span><span class="o">.</span><span class="n">binread</span><span class="p">(</span><span class="s2">&quot;puzzle_input.txt&quot;</span><span class="p">)</span>
</div></code></pre></div>
</div>
<p>通过使用 IO 类的 binread 二进制读取方法来获得不转义的字符串。</p>
]]></content:encoded></item><item><title><![CDATA[Ruby 中的 `Array.new` 中的默认值参数，指向的同一个对象]]></title><guid>https://czq.me/posts/ruby-zhong-de-array-new-zhong-de-mo-ren-zhi-can-984fb634</guid><link>https://czq.me/posts/ruby-zhong-de-array-new-zhong-de-mo-ren-zhi-can-984fb634</link><pubDate>Thu, 11 Apr 2024 06:32:42 +0000</pubDate><content:encoded><![CDATA[<p>今天写 Ruby 遇到的小坑，最后在测试下发现问题，仔细查看文档发现是我理解错了。</p>
<h2>What</h2>
<p>在做 Advent Of Code <a href="https://adventofcode.com/2015/day/6">这一题</a>的时候，需要构建一个比较大的初始值为 false 的二维数组。</p>
<p>本来打算双重循环构建的，但想想 Ruby 的语法糖这么多的语言应该有更加便利的方式。</p>
<p>于是找到了，<code>Array.new</code>，构建了如下的初始化表达式。</p>
<p><code>Array.new(1000, Array.new(1000, false))</code></p>
<p>但是遇到一个奇怪的问题，在修改二维数组中某一个值的时候，导致其他二维数组的同一个位置也会跟着修改。</p>
<h2>Why</h2>
<p>重现问题并验证。</p>
<div class="block-code" data-language="rb"><div class="highlight"><pre><span></span><code><div class="line"><span class="n">a</span> <span class="o">=</span> <span class="nb">Array</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="nb">Array</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="kp">false</span><span class="p">))</span>
</div><div class="line"><span class="c1"># =&gt; [[false, false, false], [false, false, false], [false, false, false]]</span>
</div><div class="line"><span class="n">a</span><span class="o">[</span><span class="mi">0</span><span class="o">][</span><span class="mi">0</span><span class="o">]</span> <span class="o">=</span> <span class="kp">true</span>
</div><div class="line"><span class="c1"># =&gt; [[true, false, false], [true, false, false], [true, false, false]]</span>
</div><div class="line"><span class="n">a</span><span class="o">[</span><span class="mi">0</span><span class="o">].</span><span class="n">equal?</span><span class="p">(</span><span class="n">a</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="p">)</span>
</div><div class="line"><span class="c1"># true</span>
</div></code></pre></div>
</div>
<p>子数组是同一个数组，导致修改一个子数组，其他数组也会跟着修改。</p>
<p>查看<a href="https://ruby-doc.org/3.2.2/Array.html#method-c-new">原始文档</a>，发现确实是说默认值是同一个。</p>
<h2>How</h2>
<div class="block-code" data-language="rb"><div class="highlight"><pre><span></span><code><div class="line"><span class="nb">Array</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">1000</span><span class="p">)</span> <span class="p">{</span> <span class="nb">Array</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">1000</span><span class="p">,</span> <span class="kp">false</span><span class="p">)</span> <span class="p">}</span>
</div></code></pre></div>
</div>
<h2>Summary</h2>
<p>导致理解错了的原因可能是，我还没有转化到 Ruby 中一切皆对象的思维，不再区分什么是基础类型，对象类型。在这个例子中我还在下意识的认为会对传统意义上的对象做特殊处理。</p>
<p>还是 Ruby 代码写的太少了，要多写写，习惯这种一切皆对象的思维方式。</p>
]]></content:encoded></item><item><title><![CDATA[在日本使用汉字姓名的手续]]></title><guid>https://czq.me/posts/zai-ri-ben-shi-yong-yi-zi-xing-ming-de-shou-xu-30a8e633</guid><link>https://czq.me/posts/zai-ri-ben-shi-yong-yi-zi-xing-ming-de-shou-xu-30a8e633</link><pubDate>Sun, 29 Oct 2023 15:07:43 +0000</pubDate><content:encoded><![CDATA[<p>中国护照上的名字是拼音的形式，到了日本默认的名字也是拼音的字母形式。如果想使用汉字的话，需要提交变更申请。</p>
<h2>中国汉字如何转换成日本汉字</h2>
<p>在留管理局提供了一个网站<a href="http://lapse-immi.moj.go.jp:50122/">正字検索システム</a>可以查询到中国汉字对应的可使用日本汉字。</p>
<p>有时候会存在多种情况，应该可以任选其一。</p>
<p>有些日本汉字分为旧字和新字，区别是字形有些不一样，外国人的名字中似乎只能使用旧字。</p>
<p>比如我的名字中的「强」字，日语中类似的常用字是「強」，但是工作人员和我说「強」这个字不可以用，但是可以用「强」字。</p>
<p>后来我找了一篇文章<a href="https://dictionary.sanseido-publ.co.jp/column/%E7%AC%AC105%E5%9B%9E-%E3%80%8C%E5%BC%B7%E3%80%8D%E3%81%A8%E3%80%8C%E5%BC%BA%E3%80%8D">人名用漢字の新字旧字 第105回「強」と「强」</a>，人名中的使用有一些讲究的。</p>
<div class="blockquote"><blockquote><p>その一方で法務省は、平成23年12月26日に入国管理局正字13287字を告示しました。入国管理局正字は、日本に住む外国人が住民票や在留カード等の氏名に使える漢字で、別表第一に旧字の「强」を収録していました。この結果、日本で生まれた外国人の子供の出生届には、新字の「強」に加え、旧字の「强」が書けるようになりました。でも、日本人の子供の出生届には、新字の「強」はOKですが、旧字の「强」はダメなのです。</p>
</blockquote></div>
<p>所以还是使用上面的系统查询比较方便，自己转换会有一些问题。</p>
<h2>费用</h2>
<p>费用的话，如果和在留更新一起提交的话是免费的，单独申请的话是 1600 日元。</p>
<h2>参考</h2>
<p><a href="https://www.moj.go.jp/isa/applications/guide/kanji.html">在留カードの漢字氏名表記について</a></p>
<p><a href="https://www.moj.go.jp/isa/applications/procedures/nyuukokukanri10_00019.html">在留カード漢字氏名表記申出</a></p>
]]></content:encoded></item><item><title><![CDATA[スピーチ「おすすめのアニメあしたのジョー」]]></title><guid>https://czq.me/posts/ashitanojyo-speech</guid><link>https://czq.me/posts/ashitanojyo-speech</link><pubDate>Tue, 26 Sep 2023 03:55:55 +0000</pubDate><content:encoded><![CDATA[<p>日本語学校のクラスでスピーチをしました。内容は以下となります。</p>
<h2>初めのまとめ</h2>
<p>おすすめのアニメといえば、皆さんが何が思いますか、異世界〇〇ですか、魔法〇〇ですか。</p>
<p>私は紹介したいアニメは五十年前昭和時代のボクシング運動についてのアニメ、名前はあしたのジョー。</p>
<p>主人公矢吹丈（やぶき　じょう）は不良（ふりょう）少年から世界一のボクシング選手になったというストーリー。</p>
<h2>おすすめのポイント</h2>
<p>おすすめのポイント四点があります。</p>
<p>ポイント１　主人公の成長が見えます、不良少年から夢を持つ少年に変化した、何度も倒れた、何度も立ち上がります、死ぬまで戦い。</p>
<p>ポイント２　古くて、独特(どくとく)の画面(がめん)。今の時代より画面が豊富じゃないですけど、その時代の独特のスタイルの画面が見えます。</p>
<p>ポイント３　素晴らしい音楽。いろんな特点（とくてん）があります、昭和風とか、ロックとか、シンフォニーとか、音楽から人物のきもちがよく表しました。</p>
<p>ポイント４　太平洋戦争が終わったの日本が見えます、その時急に経済(けいざい)成長が起こった時、社会問題や環境問題を分かれます。</p>
<h2>最後のまとめ</h2>
<p>矢吹丈倒れないの精神に勉強しました、自分の人生も倒れないように続けます。</p>
<p>以上お勧めしたアニメあしたのジョー、趣味がある方、是非見てみてください。</p>
<h2>リファレンス</h2>
<p><a href="https://core-choco.com/news/1838.html">写真から</a></p>
]]></content:encoded></item><item><title><![CDATA[使用 chezmoi 来做 dotfiles 管理]]></title><guid>https://czq.me/posts/shi-yong-chezmoi-lai-zuo-dotfiles-guan-li-7875d2f1</guid><link>https://czq.me/posts/shi-yong-chezmoi-lai-zuo-dotfiles-guan-li-7875d2f1</link><pubDate>Sat, 18 Mar 2023 08:45:00 +0000</pubDate><content:encoded><![CDATA[<p>管理 dotfiles 是个比较麻烦的事情，特别是在多系统下，现在还有在容器中（ devcontainer ，GitHub Codespaces ）开发，如何快速一键的配置自己的环境。之前使用过好几个工具 homeshick mackup 等等，去年开始也把包管理工具切换到 Nix 上，不过 Nix 在 MacOS 的体验有些差，MacOS 上还是好好用 Brew 吧。</p>
<p>最近又搜索相关管理工具，看到 <a href="https://www.chezmoi.io/">chezmoi</a> 这个工具，是个不错的选择，支持多系统上非常好。</p>
<p>我今天在 MacOS 上做了一个初始的<a href="https://github.com/jikyou/dotfiles">配置</a>，也可以在 GitHub Codespaces 中使用。</p>
<p>Arch Linux 的 <a href="https://wiki.archlinux.org/title/Dotfiles#Tools">Wiki</a> 总结了一些常用的 dotfiles 管理工具。</p>
]]></content:encoded></item><item><title><![CDATA[如何测试对当前时间有强依赖的应用]]></title><guid>https://czq.me/posts/ru-he-ce-shi-dui-dang-qian-shi-jian-you-qiang-yi-587e0949</guid><link>https://czq.me/posts/ru-he-ce-shi-dui-dang-qian-shi-jian-you-qiang-yi-587e0949</link><pubDate>Fri, 17 Mar 2023 12:31:35 +0000</pubDate><content:encoded><![CDATA[<p>之前做过的系统中，有些功能对当前时间有非常强的依赖。比如：任务系统中，每日刷新，每周刷新，每月刷新之类的。</p>
<p>整个迭代周期很短，留个开发和测试的时间都不多，真实的时间肯定要测试，但大量的测试还是需要依赖一个假的时间。</p>
<h2>Mock 时间</h2>
<h3>修改系统时间</h3>
<p>修改系统时间虽然比较简单，但会带来一些问题。</p>
<ol>
<li>对开发和测试都不够友好。<ol>
<li>对开发来说，需要写大量的单元测试，不可能依赖这种方式来测试功能。</li>
<li>测试需要登陆测试环境不断设置时间。</li>
</ol>
</li>
<li>集群模式下需要修改整个集群的时间，如果集群部署在一台机器上还好，但是我们使用 k8s ，只修改一个容器的时间，会导致整个集群出现问题，甚至挂掉。</li>
</ol>
<h3>修改应用的时间</h3>
<p>这个对开发和测试比较友好。</p>
<ol>
<li>单元测试非常好写。</li>
<li>并提供环境变量来注入，方便测试同学修改时间测试。</li>
</ol>
<p>Node.js 中，在应用启动的时候，把 Date 时间库包装一下就可以解决。当然社区中也有现成的包 <a href="https://www.npmjs.com/package/timeshift-js">timeshift-js</a> 解决。</p>
]]></content:encoded></item><item><title><![CDATA[阿里云集群模式下的 Redis 对 Lua 脚本存在限制]]></title><guid>https://czq.me/posts/a-li-yun-ji-qun-mo-shi-xia-de-redis-dui-lua-jiao-a1619c75</guid><link>https://czq.me/posts/a-li-yun-ji-qun-mo-shi-xia-de-redis-dui-lua-jiao-a1619c75</link><pubDate>Fri, 17 Mar 2023 10:54:35 +0000</pubDate><content:encoded><![CDATA[<p>去年年初工作时的一篇记录。</p>
<p>遇到一个关于 Redis 集群模式下的问题，是阿里云对 Lua 脚本的限制导致的，但是 <code>node-redlock</code> 包把错误吞掉了，抛出了一个重试失败的错误，导致我定位了好久…</p>
<p>被吞掉的错误信息：</p>
<div class="block-code"><pre><code>-ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array</code></pre></div>
<p><a href="https://help.aliyun.com/document_detail/92942.htm?spm=a2c4g.11186623.0.0.2c555c7dYsASSH#section-8f7-qgv-dlv">https://help.aliyun.com/document_detail/92942.htm?spm=a2c4g.11186623.0.0.2c555c7dYsASSH#section-8f7-qgv-dlv</a></p>
<h2>解决方式</h2>
<ol>
<li>在阿里云后台关闭 <code>script_check_enable</code> 这个设置。</li>
<li>或者改造脚本，只向 Redis 传递对 KEYS 的引用，而不是变量。</li>
</ol>
<h2>反思自我的问题</h2>
<p>未知的错误，网上搜索不到直接的解决方案，加上定位问题的时间不够，导致我没有定位问题的耐心，非常焦躁，希望有人可以帮我解决掉问题...</p>
<p>另一方面没有从原理的角度去思考，<code>node-redlock</code> 只是调用 Redis 的库，他的问题会有哪些地方。</p>
]]></content:encoded></item><item><title><![CDATA[有状态服务改造到无状态服务注意点]]></title><guid>https://czq.me/posts/you-zhuang-tai-fu-wu-gai-zao-dao-wu-zhuang-tai-f-53d324a4</guid><link>https://czq.me/posts/you-zhuang-tai-fu-wu-gai-zao-dao-wu-zhuang-tai-f-53d324a4</link><pubDate>Wed, 15 Feb 2023 13:07:33 +0000</pubDate><content:encoded><![CDATA[<p>之前在摩西科技工作时候的小反思，现在总结一下。</p>
<h2>为什么要做有状态服务</h2>
<ol>
<li>为了快速处理高并发的问题，我们把有竞争关系的请求都转发到同一个服务上（根据用户 id 或者竞争资源的 id 来转发），同时利用 Node.js 的单进程模型，在内存中操作数据，并异步保存。因为操作内存不会有 IO 操作，所以请求的处理顺序就是请求的到来顺序。</li>
<li>异步保存会存在数据丢失的可能性，不过我们的业务没有直接和钱相关的，所以暂时降低了可用性的考量。</li>
</ol>
<h2>为什么又要改造成无状态服务</h2>
<ol>
<li>我们希望可以接入 k8s，让 k8s 来管理日益增多的微服务，并提供动态扩缩容能力。</li>
<li>k8s 也可以做有状态服务，但是会很复杂，所以我们决定改造成无状态服务。</li>
</ol>
<h2>改造注意点</h2>
<ol>
<li>之前把有竞争关系的请求到转发到同一个服务上，现在需要通过加锁或者让 Redis lua 脚本处理竞争问题。</li>
<li>为了解决在扩容之后对数据库的压力，通过 Redis 来缓存数据，一般我们使用 Cache Aside Pattern 来读取和更新数据，更新的时候先把数据保存到数据库，再把缓存失效。</li>
<li>在内存中缓存包含其他服务的数据一定要小心。</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[区块链的无需许可 Permissionless 和终局性 Finality]]></title><guid>https://czq.me/posts/qu-kuai-lian-de-wu-xu-xu-ke-permissionless-he-zh-f3fe6331</guid><link>https://czq.me/posts/qu-kuai-lian-de-wu-xu-xu-ke-permissionless-he-zh-f3fe6331</link><pubDate>Sun, 25 Dec 2022 13:46:43 +0000</pubDate><content:encoded><![CDATA[<p>很久没关注区块链了，最近听了两期播客，学到了两个词无需许可和终局性，对区块链的理解也更加深刻了。</p>
<h2>无需许可 Permissionless</h2>
<p>无需许可的意思是参与区块链出块是否需要别人许可。</p>
<p>在 POW 中只要你购买矿机和电力就可以参与共识。而在 POS 中参与共识是需要发起交易的，而现有的节点有作恶的可能性不广播你的交易，让你无法参与共识。</p>
<p>POW 比 POS 更加具有无需许可，更加去中心化，也更具抗审查能力。</p>
<p>但是 POS 也更加符合监管的需要，也许 CKB 在 Layer1 坚持 POW，在 Layer2 去选择 POS 是更好的一条路，兼顾了无需许可的参与性和监管的需要，让区块链真的变成基础设施。</p>
<h2>终局性 Finality</h2>
<p>终局性的意思是我的这笔交易是不是真的被确认了，不会被 Revert 了。</p>
<p>POW 没有终局性，因为在理论上只要有足够的算力是可以从自己认可的区块高度开始重新出块，而达到最长链，导致其他人的出的块被丢弃，但是这是理论上。所以我们会说超过 6 个区块后，可以认为 99.99% 不会被 Revert 了。</p>
<p>终局性是很多强一致性的应用需求，比如金融类的应用。</p>
<h2>References</h2>
<p><a href="https://talk.nervos.org/t/pow-vs-pos/1732">PoW vs. PoS</a></p>
<p><a href="https://talk.nervos.org/t/fork-it-22-pow-vs-pos/6731">文字稿｜Fork It #22: PoW vs. PoS</a></p>
<p><a href="https://talk.nervos.org/t/fork-it-23-pos/6751">文字稿｜Fork It #23：PoS 是谎言么？</a></p>
]]></content:encoded></item><item><title><![CDATA[2022年9月日本語の宿題の作文]]></title><guid>https://czq.me/posts/2022nian-9yue-ri-ben-yu-nosu-ti-nozuo-wen-75689086</guid><link>https://czq.me/posts/2022nian-9yue-ri-ben-yu-nosu-ti-nozuo-wen-75689086</link><pubDate>Mon, 24 Oct 2022 13:20:09 +0000</pubDate><content:encoded><![CDATA[<h2>2022-09-07</h2>
<div class="photo"><figure><picture><source srcset="https://i.typlog.com/czqone/8230821737_032169.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230821737_032169.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230821737_032169.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230821737_032169.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230821737_032169.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230821737_032169.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230821737_032169.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230821737_032169.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230821737_032169.jpg" alt="2022-09-07.jpg"loading="lazy" decoding="async" width="3024" height="4032" /></picture></figure></div><h2>2022-09-11</h2>
<div class="photo"><figure><picture><source srcset="https://i.typlog.com/czqone/8230821737_032499.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230821737_032499.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230821737_032499.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230821737_032499.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230821737_032499.jpg" alt="2022-09-11.jpg"loading="lazy" decoding="async" /></picture></figure></div><h2>2022-09-18</h2>
<div class="photo"><figure><picture><source srcset="https://i.typlog.com/czqone/8230821737_019785.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230821737_019785.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230821737_019785.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230821737_019785.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230821737_019785.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230821737_019785.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230821737_019785.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230821737_019785.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230821737_019785.jpg" alt="2022-09-18.jpg"loading="lazy" decoding="async" width="3024" height="3024" /></picture></figure></div><h2>2022-09-19</h2>
<div class="photo"><figure><picture><source srcset="https://i.typlog.com/czqone/8230821737_011075.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230821737_011075.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230821737_011075.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230821737_011075.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230821737_011075.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230821737_011075.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230821737_011075.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230821737_011075.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230821737_011075.jpg" alt="2022-09-19.jpg"loading="lazy" decoding="async" width="3024" height="3024" /></picture></figure></div><h2>2022-09-21</h2>
<div class="photo"><figure><picture><source srcset="https://i.typlog.com/czqone/8230821737_01878.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230821737_01878.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230821737_01878.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230821737_01878.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230821737_01878.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230821737_01878.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230821737_01878.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230821737_01878.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230821737_01878.jpg" alt="2022-09-21.jpg"loading="lazy" decoding="async" width="3024" height="3024" /></picture></figure></div><h2>2022-09-25</h2>
<div class="photo"><figure><picture><source srcset="https://i.typlog.com/czqone/8230821736_825072.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230821736_825072.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230821736_825072.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230821736_825072.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230821736_825072.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230821736_825072.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230821736_825072.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230821736_825072.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230821736_825072.jpg" alt="2022-09-25.jpg"loading="lazy" decoding="async" width="3024" height="3024" /></picture></figure></div>]]></content:encoded></item><item><title><![CDATA[2022年8月日本語の宿題の作文]]></title><guid>https://czq.me/posts/2022nian-8yue-ri-ben-yu-nosu-ti-nozuo-wen-01768190</guid><link>https://czq.me/posts/2022nian-8yue-ri-ben-yu-nosu-ti-nozuo-wen-01768190</link><pubDate>Sat, 20 Aug 2022 00:34:37 +0000</pubDate><content:encoded><![CDATA[<h2>2022-08-04 おすすめのレストラン</h2>
<p>レストラン紫オレンジ食堂</p>
<p>紫オレンジ食堂は中華料理の食堂です</p>
<p>料理が安くて、便利なのでよく行きます</p>
<p>この店で私がいつも食べるのはとりの唐揚（からあ）げとマーラータンです</p>
<p>この店は、とても便利なところにあります</p>
<p>やかったら行ってみてください</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230821288_338751.jpg" alt="2022-08-04.jpg" /></picture></figure></div><h2>2022-08-08 旅行についての質問</h2>
<p>青木先生</p>
<p>こんにちはお元気ですか</p>
<p>島根県で足立美術館にいてみたいんですが、八月はどうですか</p>
<p>どんなえがおすすめですか</p>
<p>みているとき、写真を撮った方がいいですか</p>
<p>時間がある時、教えてください</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230821288_335264.jpg" alt="2022-08-08.jpg" /></picture></figure></div><h2>2022-08-11 ボランテイアのもうしこみ</h2>
<p>青木さま</p>
<p>初めまして私はチェンと言います</p>
<p>にほんぼん踊りのボランテイアをしたいと思っています</p>
<p>私は日本の歴史と文化にとても興味があります</p>
<p>日本語は上手ないですが、かんたんな日本語だったらはなせます</p>
<p>がんばりますのでよろしくおねがいします</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230821288_110197.jpg" alt="2022-08-11.jpg" /></picture></figure></div><h2>2022-08-18 季節のお祝い</h2>
<p>青木さん</p>
<p>今年はどんな年でしたか</p>
<p>私は留学の準備が忙しかったです</p>
<p>そしてコロナがいつもあるから、どこへも行けなくて、残念でした</p>
<p>来年は日本に行きたいです</p>
<p>どうそよいねをむかえください</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230821288_314362.jpg" alt="2022-08-18.jpg" /></picture></figure></div><h2>2022-08-22 電気製品についてのしつもん</h2>
<p>青木さん</p>
<p>こんにちはちょっと教えてください</p>
<p>いつも使ったスマホが壊れしまいました</p>
<p>昨日新しいのをかった、でもスクリーンショットの方はわかりません</p>
<p>青木さんが使っているのはどうですか</p>
<p>知るなら、ぜひ教えてください</p>
<p>チェん</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230821288_311943.jpg" alt="2022-08-22.jpg" /></picture></figure></div><h2>2022-08-25 私の街の歴史と文化</h2>
<p>これはおんきんきんじょうというしろです、南京にあります。</p>
<p>14世紀にしゅげんしょうによって立てられました、城が長くて、綺麗な城門がたくさなります。</p>
<p>歩くのとき、色々なう風景があります、にぎやかなまちや、学校で遊ぶこどもたちや、静かな公園をみて、楽しめます。</p>
<p>ぜひいてみてください。</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230821288_316646.jpg" alt="2022-08-25.jpg" /></picture></figure></div><h2>2022-08-31 私のエコ活動</h2>
<p>私はごみを減らすために、できるだけスーパーで必要なものだけ買うようにしています</p>
<p>それから、空気を汚さないように電車や自転車を使うようにしています</p>
<p>できることを少しずつしたいと思います</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230821288_312723.jpg" alt="2022-08-31.jpg" /></picture></figure></div>]]></content:encoded></item><item><title><![CDATA[2022年7月日本語の宿題の作文]]></title><guid>https://czq.me/posts/2022nian-7yue-ri-ben-yu-nosu-ti-nozuo-wen-1700aeff</guid><link>https://czq.me/posts/2022nian-7yue-ri-ben-yu-nosu-ti-nozuo-wen-1700aeff</link><pubDate>Mon, 11 Jul 2022 10:24:16 +0000</pubDate><content:encoded><![CDATA[<h2>2022-07-01 遅れます</h2>
<p>すみません</p>
<p>ねすごして、十分ぐらい遅れます</p>
<p>昨日ちょっと疲れましたから</p>
<p>じゃあ、また後で</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820992_112408.jpg" alt="2022-07-01.jpg" /></picture></figure></div><h2>2022-07-10 私の外国語</h2>
<p>私は仕事がない時、日本語を勉強しています</p>
<p>日本語は中国語と違います</p>
<p>日本語はカタカナの単語を書くのが難しいです</p>
<p>でも日本語の漢字は簡単です</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820992_106328.jpg" alt="2022-07-10.jpg" /></picture></figure></div><h2>2022-07-13 来週の食事</h2>
<p>ワンさん</p>
<p>来週の鍋（なべ）パーティー楽しみですね</p>
<p>私は飲みものを持って行きます</p>
<p>ワンさんはコーラとジュースとどちらでがいいですか</p>
<p>教えてください</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820992_106789.jpg" alt="2022-07-13.jpg" /></picture></figure></div><h2>2022-07-19 出張</h2>
<p>青木先生</p>
<p>メールありがとうございました</p>
<p>私はちょっと忙しいですが、元気です</p>
<p>来週の出張よろしく御願いします</p>
<p>出発時間は午前九時、到着時間は午後八時、フライトはJF071です</p>
<p>青木先生は中国のビールを飲んだことがありますか</p>
<p>出張の時、お土産に持って行きます</p>
<p>チェン</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820992_103792.jpg" alt="2022-07-19.jpg" /></picture></figure></div><h2>2022-07-22 健康の相談</h2>
<p>運動をするといいですよ</p>
<p>ちょうと汗をかくのがいいですから</p>
<p>私は時々ジョギングをします</p>
<p>それから温かいお風呂に入るといいですよ</p>
<p>それから長い時間寝るといいですよ</p>
<p>良かったらやってみてください</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820992_112902.jpg" alt="2022-07-22.jpg" /></picture></figure></div><h2>2022-07-29 私の趣味</h2>
<p>私はよく音楽を聞きます</p>
<p>いつもアップルミュージックで聞いています</p>
<p>フェスティバルに行って、生で音楽を聞いてみたいです</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820992_113949.jpg" alt="2022-07-29.jpg" /></picture></figure></div>]]></content:encoded></item><item><title><![CDATA[2022年6月日本語の宿題の作文]]></title><guid>https://czq.me/posts/2022nian-6yue-ri-ben-yu-nosu-ti-nozuo-wen-71c5d13b</guid><link>https://czq.me/posts/2022nian-6yue-ri-ben-yu-nosu-ti-nozuo-wen-71c5d13b</link><pubDate>Tue, 05 Jul 2022 14:23:00 +0000</pubDate><content:encoded><![CDATA[<h2>2022-06-01 私の趣味</h2>
<p>私の趣味</p>
<p>こんにちは、私はチェです</p>
<p>私の趣味は音楽です</p>
<p>とくにロックとJポップと広東ごの歌が好きです</p>
<p>よくうちと会社で音楽を聴きます</p>
<p>ジョギングは時々します</p>
<p>どうぞよろしくお願いします</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820692_519764.jpg" alt="2022-06-01.jpg" /></picture></figure></div><h2>2022-06-06 うちから実家(じっか)まで</h2>
<p>うちから実家まで</p>
<p>私はうちがらビンカン駅まで歩いて行きます</p>
<p>ビンカン駅からこうじゅう東駅まで地下鉄で行きます</p>
<p>こうじゅう東駅で高速鉄道に乗ります</p>
<p>ドンタイ駅で高速鉄道をおります</p>
<p>ドンタイ駅から実家までバスで行きます</p>
<p>うちから実家まで五時間です</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820692_523397.jpg" alt="2022-06-06.jpg" /></picture></figure></div><h2>2022-06-09 先月の買い物</h2>
<p>私は先月買い物に行きました</p>
<p>インタネットでパンとストックを買いました</p>
<p>インタネットで牛乳とスキンケア商品を買いました</p>
<p>母にあげました</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820692_515296.jpg" alt="2022-06-09.jpg" /></picture></figure></div><h2>2022-06-16 休みの日</h2>
<p>先週の日曜日の午前うちにしました</p>
<p>うちで掃除をしました</p>
<p>そして午後会社に行きました</p>
<p>会社で日本語が勉強しました</p>
<p>会社で勉強すると、私はもっと集中（しゅうちゅう）できます。</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820692_519389.jpg" alt="2022-06-16.jpg" /></picture></figure></div><h2>2022-06-20 て形の作り方</h2>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820692_345596.jpg" alt="2022-06-20.jpg" /></picture></figure></div><h2>2022-06-22 私の家族</h2>
<p>私の家族</p>
<p>家族は四人です</p>
<p>父と母と祖父と私です</p>
<p>父の仕事は建設労働者です</p>
<p>建築会社で働いています</p>
<p>建築会社にでんどうじてんしゃで行きます</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820692_516557.jpg" alt="2022-06-22.jpg" /></picture></figure></div><h2>2022-06-27 好きな季節</h2>
<p>好きな季節</p>
<p>こうしゅうには季節が四つあります</p>
<p>春、夏、秋、冬です</p>
<p>私は暖かいのが好きですから、春が好きです</p>
<p>でも暑いのは好きじゃないですから、夏は好きじゃないです</p>
<p>春は三月から五月ごろです</p>
<p>夏は六月から九月ごろです</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820692_324758.jpg" alt="2022-06-27.jpg" /></picture></figure></div><h2>2022-06-30 私の町</h2>
<p>私の街</p>
<p>ここは飛来峰です</p>
<p>近いはれいいんじやせいこなどがあります</p>
<p>綺麗で人気があります</p>
<p>ぜひ行ってみてください</p>
<div class="photo"><figure><picture><img src="https://i.typlog.com/czqone/8230820692_523304.jpg" alt="2022-06-30.jpg" /></picture></figure></div>]]></content:encoded></item><item><title><![CDATA[2022年5月日本語の宿題の作文]]></title><guid>https://czq.me/posts/2022nian-5yue-ri-ben-yu-nosu-ti-nozuo-wen-a32b3acb</guid><link>https://czq.me/posts/2022nian-5yue-ri-ben-yu-nosu-ti-nozuo-wen-a32b3acb</link><pubDate>Tue, 05 Jul 2022 13:04:00 +0000</pubDate><content:encoded><![CDATA[<h2>2022-05-16 私の朝ごはん</h2>
<p>私はいつもごはんを食べます。</p>
<p>野菜と肉も食べます。</p>
<p>豆腐はあまり食べせん。</p>
<p>よくコーラを飲みます。</p>
<p>お茶はあまりすきじゃないです。</p>
<div class="photo"><figure><picture><source srcset="https://i.typlog.com/czqone/8230820510_480685.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230820510_480685.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230820510_480685.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230820510_480685.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230820510_480685.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230820510_480685.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230820510_480685.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230820510_480685.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230820510_480685.jpg" alt="2022-05-16.jpg"loading="lazy" decoding="async" width="3024" height="4032" /></picture></figure></div><h2>2022-05-23 私の家</h2>
<p>私の家は江蘇省あります。</p>
<p>私の家は一戸建てです。</p>
<p>私の家は新しくないです、じゅうきゅうねんの歴史があります。</p>
<p>私の父は祖父とすんでいます。</p>
<p>猫はいません。ほかの人の犬が時々遊びに来ます。</p>
<div class="photo"><figure><picture><source srcset="https://i.typlog.com/czqone/8230820510_476328.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230820510_476328.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230820510_476328.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230820510_476328.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230820510_476328.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230820510_476328.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230820510_476328.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230820510_476328.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230820510_476328.jpg" alt="2022-05-23.jpg"loading="lazy" decoding="async" width="3024" height="4032" /></picture></figure></div><h2>2022-05-28 私の一日</h2>
<p>これは私の一日</p>
<p>七時に起きます。</p>
<p>九時に会社に行きます。</p>
<p>九時十分に朝ご飯を食べます。</p>
<p>夜七時ごろうちに帰ります。</p>
<p>日本語を勉強します。</p>
<p>時々ユーチューブを見ます。</p>
<p>十一時にシャワーを浴びます。</p>
<p>十二時ごろ寝ます。</p>
<div class="photo"><figure><picture><source srcset="https://i.typlog.com/czqone/8230820510_444244.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500/format,webp 1x, https://i.typlog.com/czqone/8230820510_444244.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000/format,webp 2x" media="(min-width: 1500px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230820510_444244.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1500 1x, https://i.typlog.com/czqone/8230820510_444244.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_3000 2x" media="(min-width: 1500px)"><source srcset="https://i.typlog.com/czqone/8230820510_444244.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800/format,webp 1x, https://i.typlog.com/czqone/8230820510_444244.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600/format,webp 2x" media="(min-width: 800px)" type="image/webp"><source srcset="https://i.typlog.com/czqone/8230820510_444244.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_800 1x, https://i.typlog.com/czqone/8230820510_444244.jpg?x-oss-process=image/auto-orient,1/interlace,1/quality,q_90/resize,m_lfit,w_1600 2x" media="(min-width: 800px)"><img src="https://i.typlog.com/czqone/8230820510_444244.jpg" alt="2022-05-28.jpg"loading="lazy" decoding="async" width="3024" height="3024" /></picture></figure></div>]]></content:encoded></item><item><title><![CDATA[JS 中实现循环固定次数的语法糖]]></title><guid>https://czq.me/posts/js-zhong-shi-xian-xun-huan-gu-ding-ci-shu-de-yu-49362a46</guid><link>https://czq.me/posts/js-zhong-shi-xian-xun-huan-gu-ding-ci-shu-de-yu-49362a46</link><pubDate>Sun, 29 May 2022 12:57:48 +0000</pubDate><content:encoded><![CDATA[<p>有一些场景需要循环固定次数来执行一些操作，比如失败重试固定次数，制造固定数量的假数据等。</p>
<p>在 JS 中实现的时候，我一直使用最简单的 for 版本，但是一方面他是我代码中为数不多的声明式的循环写法，同时也产生了不必要的变量，相比声明式的写法可读性也稍微差一些。</p>
<p>之前一直使用的循环版本。</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">let</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mf">10</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">doSomething</span><span class="p">();</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div></code></pre></div>
</div>
<p>在其他语言中，比如 Ruby 中可以这么实现：</p>
<div class="block-code" data-language="ruby"><div class="highlight"><pre><span></span><code><div class="line"><span class="mi">5</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="nb">print</span> <span class="s2">&quot;1&quot;</span> <span class="p">}</span>
</div></code></pre></div>
</div>
<p>在 Python3 中可以这么实现：</p>
<div class="block-code" data-language="py"><div class="highlight"><pre><span></span><code><div class="line"><span class="kn">import</span> <span class="nn">itertools</span>
</div><div class="line">
</div><div class="line"><span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">repeat</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">n</span><span class="p">):</span>
</div><div class="line">    <span class="n">foo</span><span class="p">()</span>
</div></code></pre></div>
</div>
<p>最近在写 JS 中又遇到这个问题，搜索一番，综合各家方案，我选择一个具有声明式，同时可读性也不差的写法。</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="nb">Array</span><span class="p">.</span><span class="kr">from</span><span class="p">({</span><span class="nx">length</span><span class="o">:</span><span class="w"> </span><span class="mf">3</span><span class="p">}).</span><span class="nx">map</span><span class="p">(()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">doSomething</span><span class="p">());</span><span class="w"></span>
</div></code></pre></div>
</div>
<p>当然所有简化写法的目标都是围绕着制造一个有固定数量的 undefined 元素的数组而做的。</p>
<p>更简洁但是可读性差一些的方案。</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="p">[...</span><span class="nb">Array</span><span class="p">(</span><span class="mf">3</span><span class="p">)].</span><span class="nx">map</span><span class="p">(()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">doSomething</span><span class="p">());</span><span class="w"></span>
</div></code></pre></div>
</div>
<h2>References</h2>
<p><a href="https://stackoverflow.com/questions/30452263/is-there-a-mechanism-to-loop-x-times-in-es6-ecmascript-6-without-mutable-varia">https://stackoverflow.com/questions/30452263/is-there-a-mechanism-to-loop-x-times-in-es6-ecmascript-6-without-mutable-varia</a></p>
]]></content:encoded></item><item><title><![CDATA[在 Bash 中快速执行历史命令的小技巧]]></title><guid>https://czq.me/posts/zai-bash-zhong-kuai-su-zhi-xing-li-shi-ming-ling-778ab45b</guid><link>https://czq.me/posts/zai-bash-zhong-kuai-su-zhi-xing-li-shi-ming-ling-778ab45b</link><pubDate>Mon, 04 Apr 2022 07:58:00 +0000</pubDate><content:encoded><![CDATA[<p>最简单的方式是使用 <code>Ctrl + r</code> 快速搜索已经执行过的历史命令，然后回车就可以快速执行命令了。</p>
<h2>reverse-search-history</h2>
<p>19 年的时候，我购买了 <a href="https://twitter.com/linuxtoy">Linuxtoy</a> 出的一个关于命令行的使用指南<a href="https://selfhostedserver.com/usingcli-book">「像黑客一样使用命令行」</a>。从中学到了一个小技巧就一直使用到了现在。</p>
<p>这个小技巧就是 reverse-search-history 。通过在 Bash 中 <code>Ctrl + r</code> 快速搜索已经执行过的历史命令，然后回车就可以达到快速执行命令了。</p>
<p><a href="https://www.gnu.org/software/bash/manual/html_node/Commands-For-History.html">reverse-search-history</a>，可以追溯的文档是在 关于 Bash 的手册 <a href="https://www.gnu.org/software/bash/manual/html_node/Bash-History-Facilities.html">manual</a> 。</p>
<p>目前 Bash 和 Zsh 都支持这个操作，但是 <a href="https://fishshell.com/">Fish Shell</a> 不支持这个特性，参考 <a href="https://github.com/fish-shell/fish-shell/issues/602">Issues</a> ，所以那时候我又用回 Zsh 了。</p>
<h2>fzf - fuzzy finder</h2>
<p><code>Ctrl + r</code> 快捷键搜索的好处是 Bash 自带的，适合在服务器上使用，不用安装任何插件，缺点是但是对搜索不够友好，不能够模糊搜索。</p>
<p>而 <a href="https://github.com/junegunn/fzf">fzf</a> 可以做到模糊搜索，适合在本地开发机使用。安装和使用可以参考 Github 的文档。</p>
<h2>Auto suggestions</h2>
<p>有些插件或者 shell 可以根据历史执行过的命令，自动建议命令，触发条件是需要先在命令行输入需要执行命令。插件会根据前缀匹配出最近的一条历史命令，通过 <code>Ctrl + e</code> 加回车执行命令。当然缺点也是只能根据输入的前缀来匹配命令，和之前的方案相比各有用途。</p>
<ol>
<li>zsh 插件 <a href="https://github.com/zsh-users/zsh-autosuggestions">zsh-autosuggestions</a> 。</li>
<li>fish shell 自带 Autosuggestions。</li>
</ol>
<h2>Reference</h2>
<p><a href="https://www.baeldung.com/linux/bash-using-history-efficiently">Bash – Using History Efficiently</a></p>
]]></content:encoded></item><item><title><![CDATA[[10, 2, 1].sort() 在 JS 中会输出什么]]></title><guid>https://czq.me/posts/10-2-1-sort-zai-js-zhong-hui-shu-chu-shi-yao-b9942a48</guid><link>https://czq.me/posts/10-2-1-sort-zai-js-zhong-hui-shu-chu-shi-yao-b9942a48</link><pubDate>Wed, 16 Mar 2022 14:40:56 +0000</pubDate><content:encoded><![CDATA[<p>在准备面试题的时候，想起了一个在 18 年掉过的坑。关于 JavaScript 中 <code>Array.prototype.sort()</code> 的默认排序数据类型。</p>
<p>（希望问别人这个问题，不会在背后被人骂。）</p>
<h2>是什么</h2>
<p>一些没掉过坑的同学，可能会说当然是 <code>[1, 2, 10]</code> 啦。</p>
<p>但是如果你看过 MDN 的关于 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort"><code>Array.prototype.sort()</code></a> 的文档，你就会知道这个结果是错误的，文档中的第一句话和第二例子就是对这个问题的描述。</p>
<p>那么，答案是什么呢，答案是 <code>[ 1, 10, 2 ]</code>。</p>
<p>为什么呢，看 MDN 原文：</p>
<div class="blockquote"><blockquote><p>The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.</p>
</blockquote></div>
<p><code>sort()</code> 函数的默认排序是正序，以及排序的的时候会把所有元素都转化成字符串，然后再排序。字符串排序首先是按照第一个字符进行排序的，再者第一个字符相同的排第二个字符，所以最后的结果是 <code>[ 1, 10, 2 ]</code>。</p>
<p>然而编译器为什么要这么做呢？</p>
<h2>为什么</h2>
<p>首先当然是语言的标准定义这么做的，编译器只是对标准的实现。在 JS 中这个标准就是 <a href="https://tc39.es/ecma262/multipage/">ECMAScript</a> 。</p>
<p>在 <a href="https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.sort"><code>Array.prototype.sort()</code></a> 的标准定义中说：</p>
<div class="block-code" data-language="md"><div class="highlight"><pre><span></span><code><div class="line">d. If comparefn is not undefined, then
</div><div class="line">    i. Let v be ? ToNumber(? Call(comparefn, undefined, « x, y »)).
</div><div class="line">    ii. If v is NaN, return +0𝔽.
</div><div class="line">    iii. Return v.
</div><div class="line">e. Let xString be ? ToString(x).
</div><div class="line">f. Let yString be ? ToString(y).
</div><div class="line">g. Let xSmaller be ! IsLessThan(xString, yString, true).
</div></code></pre></div>
</div>
<p>上面的意思是说，如果 sort 中没有传入比较函数，那么就将需要比较的元素，进行 <code>ToString()</code> 转化后在比较。</p>
<p>那么为什么标准需要这么处理呢？</p>
<p>这里我大胆的猜一猜，找一找借口...。</p>
<ol>
<li>首先 <code>sort()</code> 函数并不是指针对数字进行排序的，还有其他所有类型都可以传入，为了保证函数的语意明确，统一进行 <code>ToString()</code> 操作。</li>
<li>其次我们看下 <a href="https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tostring"><code>ToString()</code></a> 在规范中的定义，除了对 Symbol 类型调用 <code>ToString()</code> 会抛异常，其他类型都是可以使用 <code>ToString()</code> 转化的，所以这也是一个的把未知转化成已知类型的操作，非常干净。</li>
</ol>
<p>所以为什么不对数字进行特殊处理呢？这就不知道了，不过我们可以站语言标准的制定者的角度思考的问题角度，你愿意在标准中让一些方法对一个类型进行特殊处理吗？</p>
<p>题外话，基于以上 <code>ToString()</code> 的例子，我想到有些很奇怪的面试考就是考你，对特殊类型进行加号操作会输出什么，不外呼就是转型成 String 后拼接。</p>
<h2>怎么做</h2>
<p>那么就传入排序函数吧。</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="p">[</span><span class="mf">10</span><span class="p">,</span><span class="w"> </span><span class="mf">2</span><span class="p">,</span><span class="w"> </span><span class="mf">1</span><span class="p">].</span><span class="nx">sort</span><span class="p">((</span><span class="nx">a</span><span class="p">,</span><span class="w"> </span><span class="nx">b</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">b</span><span class="p">);</span><span class="w"></span>
</div></code></pre></div>
</div>
]]></content:encoded></item><item><title><![CDATA[关于 if/else 和 for 的可读性问题]]></title><guid>https://czq.me/posts/guan-yu-if-else-he-for-de-ke-du-xing-wen-ti-f1eec24e</guid><link>https://czq.me/posts/guan-yu-if-else-he-for-de-ke-du-xing-wen-ti-f1eec24e</link><pubDate>Tue, 15 Mar 2022 13:12:49 +0000</pubDate><content:encoded><![CDATA[<p>谈谈关于代码中 if/else 和 for 语句的可读性问题。</p>
<p>可读性意味着可维护性，可维护性又关联着个人和他人维护的效率。维护代码过程中，我们阅读代码的时间肯定要比写代码的时间长，部分决定了 Bug 需要花多长的时间去接口，所以可读性还是很重要的。</p>
<p>（在和朋友讨论的过程中，发生了一个争论，关于可读性和性能的优先级，从而有了重写这篇博客的想法。主要改动了结构和增加了关于可读性和性能的讨论。）</p>
<h2>问题</h2>
<p>首先看一张很久以前见过，非常耸人听闻的嵌套代码。图中代码的问题是，嵌套层级太深，会导致读代码读到中间的时候已经忘记之前的判定条件是什么。</p>
<p>在我们项目的代码里虽然没有这么夸张，但是嵌套三/四层有时候还是会见到的。虽然在早期公司商业模式没有验证，代码质量比较差可以理解，但是给后来的同学给出来不好的榜样。</p>
<p>所以我们的重构目标就是要去掉多层的缩进，减少阅读代码的负担。</p>
<h2>if/else</h2>
<p>上面的例子太夸张，这里举一些简单一些的例子，重构手法是一致的。</p>
<h3>例子一</h3>
<p>这是一段做 EPUB 格式的电子书分发的代码。需要根据书的 id 查询出所有的电子书版本，然后判定书籍的电子版的有效性，有效的话需要去注册 ISBN 信息，注册成功的版本需要发出通知。</p>
<p>这里问题是有三层嵌套，要简化逻辑，我们要拆掉嵌套。</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">distributeEpubs</span><span class="p">(</span><span class="nx">bookId</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="nx">epubs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">getEpubsByBookId</span><span class="p">(</span><span class="nx">bookId</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">let</span><span class="w"> </span><span class="nx">epub</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="nx">epubs</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">epub</span><span class="p">.</span><span class="nx">isValid</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="kd">let</span><span class="w"> </span><span class="nx">registered</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">registerIsbn</span><span class="p">(</span><span class="nx">epub</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">registered</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">                </span><span class="nx">sendEpub</span><span class="p">(</span><span class="nx">epub</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div></code></pre></div>
</div>
<p>要拆嵌套，我们先想到的是可以把循环里面抽出一个函数出来。（这里的循环我们在下面重构）</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">distributeEpubs1</span><span class="p">(</span><span class="nx">bookId</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="nx">epubs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">getEpubsByBookId</span><span class="p">(</span><span class="nx">bookId</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">let</span><span class="w"> </span><span class="nx">epub</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="nx">epubs</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="nx">distributeEpub</span><span class="p">(</span><span class="nx">epub</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">distributeEpub</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">epub</span><span class="p">.</span><span class="nx">isValid</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="nx">registered</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">registerIsbn</span><span class="p">(</span><span class="nx">epub</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">registered</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="nx">sendEpub</span><span class="p">(</span><span class="nx">epub</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div></code></pre></div>
</div>
<p>其次 if 嵌套可以先把处理完的返回，一般都是先把错误情况处理完就返回。</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">distributeEpub</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">epub</span><span class="p">.</span><span class="nx">isValid</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="nx">registered</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">registerIsbn</span><span class="p">(</span><span class="nx">epub</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">registered</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">sendEpub</span><span class="p">(</span><span class="nx">epub</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div></code></pre></div>
</div>
<p>只有一层嵌套，非常漂亮。</p>
<h3>例子二</h3>
<p>这是一个网络聊天室，只有两个人都连接上才能聊天。这里还是嵌套的问题，还有 else 的问题。</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">ConnectPeer2Peer</span><span class="p">(</span><span class="nx">pA</span><span class="p">,</span><span class="w"> </span><span class="nx">pB</span><span class="p">,</span><span class="w"> </span><span class="nx">manager</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">pA</span><span class="p">.</span><span class="nx">isConnected</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="nx">manager</span><span class="p">.</span><span class="nx">Prepare</span><span class="p">(</span><span class="nx">pA</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">pB</span><span class="p">.</span><span class="nx">isConnected</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="nx">manager</span><span class="p">.</span><span class="nx">Prepare</span><span class="p">(</span><span class="nx">pB</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">manager</span><span class="p">.</span><span class="nx">ConnectTogther</span><span class="p">(</span><span class="nx">pA</span><span class="p">,</span><span class="w"> </span><span class="nx">pB</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">                </span><span class="nx">pA</span><span class="p">.</span><span class="nx">Write</span><span class="p">(</span><span class="s2">&quot;connected&quot;</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">                </span><span class="nx">pB</span><span class="p">.</span><span class="nx">Write</span><span class="p">(</span><span class="s2">&quot;connected&quot;</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">                </span><span class="k">return</span><span class="w"> </span><span class="nx">S_OK</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">                </span><span class="k">return</span><span class="w"> </span><span class="nx">S_ERROR</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="w">        </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="nx">pA</span><span class="p">.</span><span class="nx">Write</span><span class="p">(</span><span class="s2">&quot;Peer is not Ready, waiting...&quot;</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="nx">S_RETRY</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">pB</span><span class="p">.</span><span class="nx">isConnected</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="nx">pB</span><span class="p">.</span><span class="nx">Write</span><span class="p">(</span><span class="s2">&quot;Peer is not Ready, waiting...&quot;</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="nx">S_RETRY</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="nx">pA</span><span class="p">.</span><span class="nx">Close</span><span class="p">();</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="nx">pB</span><span class="p">.</span><span class="nx">Close</span><span class="p">();</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="nx">S_ERROR</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div></code></pre></div>
</div>
<p>按照我的习惯，会把有预期的错误都处理完，最后可以无嵌套的处理成功的情况。</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">ConnectPeer2Peer</span><span class="p">(</span><span class="nx">pA</span><span class="p">,</span><span class="w"> </span><span class="nx">pB</span><span class="p">,</span><span class="w"> </span><span class="nx">manager</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">pA</span><span class="p">.</span><span class="nx">isConnected</span><span class="p">()</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="o">!</span><span class="nx">pB</span><span class="p">.</span><span class="nx">isConnected</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="nx">pA</span><span class="p">.</span><span class="nx">Close</span><span class="p">();</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="nx">pB</span><span class="p">.</span><span class="nx">Close</span><span class="p">();</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nx">S_ERROR</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">pA</span><span class="p">.</span><span class="nx">isConnected</span><span class="p">()</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="nx">pB</span><span class="p">.</span><span class="nx">isConnected</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="nx">manager</span><span class="p">.</span><span class="nx">Prepare</span><span class="p">(</span><span class="nx">pA</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="nx">pA</span><span class="p">.</span><span class="nx">Write</span><span class="p">(</span><span class="s2">&quot;Peer is not Ready, waiting...&quot;</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nx">S_RETRY</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">pA</span><span class="p">.</span><span class="nx">isConnected</span><span class="p">()</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="nx">pB</span><span class="p">.</span><span class="nx">isConnected</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="nx">manager</span><span class="p">.</span><span class="nx">Prepare</span><span class="p">(</span><span class="nx">pB</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="nx">pB</span><span class="p">.</span><span class="nx">Write</span><span class="p">(</span><span class="s2">&quot;Peer is not Ready, waiting...&quot;</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nx">S_RETRY</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">manager</span><span class="p">.</span><span class="nx">ConnectTogther</span><span class="p">(</span><span class="nx">pA</span><span class="p">,</span><span class="w"> </span><span class="nx">pB</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nx">S_ERROR</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="w">    </span><span class="nx">pA</span><span class="p">.</span><span class="nx">Write</span><span class="p">(</span><span class="s2">&quot;connected&quot;</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">pB</span><span class="p">.</span><span class="nx">Write</span><span class="p">(</span><span class="s2">&quot;connected&quot;</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">S_OK</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div></code></pre></div>
</div>
<h3>例子三</h3>
<p>这个坏味道在我们的代码中也比较常见，就是重复的 if/else 或者 switch/case 。</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">getBookPrice</span><span class="p">(</span><span class="nx">user</span><span class="p">,</span><span class="w"> </span><span class="nx">book</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="nx">price</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">book</span><span class="p">.</span><span class="nx">getPrice</span><span class="p">();</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">switch</span><span class="w"> </span><span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">getLevel</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">case</span><span class="w"> </span><span class="nx">UserLevel</span><span class="p">.</span><span class="nx">SILVER</span><span class="o">:</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="nx">price</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.9</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">case</span><span class="w"> </span><span class="nx">UserLevel</span><span class="p">.</span><span class="nx">GOLD</span><span class="o">:</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="nx">price</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.8</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">case</span><span class="w"> </span><span class="nx">UserLevel</span><span class="p">.</span><span class="nx">PLATINUM</span><span class="o">:</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="nx">price</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.75</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">default</span><span class="o">:</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="nx">price</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">getEpubPrice</span><span class="p">(</span><span class="nx">user</span><span class="p">,</span><span class="w"> </span><span class="nx">epub</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="nx">price</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">epub</span><span class="p">.</span><span class="nx">getPrice</span><span class="p">();</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">switch</span><span class="w"> </span><span class="p">(</span><span class="nx">user</span><span class="p">.</span><span class="nx">getLevel</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">case</span><span class="w"> </span><span class="nx">UserLevel</span><span class="p">.</span><span class="nx">SILVER</span><span class="o">:</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="nx">price</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.95</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">case</span><span class="w"> </span><span class="nx">UserLevel</span><span class="p">.</span><span class="nx">GOLD</span><span class="o">:</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="nx">price</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.85</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">case</span><span class="w"> </span><span class="nx">UserLevel</span><span class="p">.</span><span class="nx">PLATINUM</span><span class="o">:</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="nx">price</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.8</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">default</span><span class="o">:</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="nx">price</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div></code></pre></div>
</div>
<p>这里重复的问题是缺少关于 level 的模型，我们可以通过增加 UserLevel 的模型把重复的 if/else 去掉。我这里给出 typescrite 的版本，通过显示的接口说明对外屏蔽细节。</p>
<div class="block-code" data-language="typescript"><div class="highlight"><pre><span></span><code><div class="line"><span class="kd">interface</span><span class="w"> </span><span class="nx">IUserLevel</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">getBookPrice</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">book</span><span class="o">:</span><span class="w"> </span><span class="kt">Book</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="kt">number</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">getEpubPrice</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">epub</span><span class="o">:</span><span class="w"> </span><span class="kt">Epub</span><span class="p">)</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="kt">number</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="kd">class</span><span class="w"> </span><span class="nx">RegularUserLevel</span><span class="w"> </span><span class="k">implements</span><span class="w"> </span><span class="nx">IUserLevel</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">getBookPrice</span><span class="p">(</span><span class="nx">book</span><span class="o">:</span><span class="w"> </span><span class="kt">Book</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nx">book</span><span class="p">.</span><span class="nx">getPrice</span><span class="p">();</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">getEpubPrice</span><span class="p">(</span><span class="nx">epub</span><span class="o">:</span><span class="w"> </span><span class="kt">Epub</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nx">epub</span><span class="p">.</span><span class="nx">getPrice</span><span class="p">();</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="kd">class</span><span class="w"> </span><span class="nx">SilverUserLevel</span><span class="w"> </span><span class="k">implements</span><span class="w"> </span><span class="nx">IUserLevel</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">getBookPrice</span><span class="p">(</span><span class="nx">book</span><span class="o">:</span><span class="w"> </span><span class="kt">Book</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nx">book</span><span class="p">.</span><span class="nx">getPrice</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.9</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">getEpubPrice</span><span class="p">(</span><span class="nx">epub</span><span class="o">:</span><span class="w"> </span><span class="kt">Epub</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nx">epub</span><span class="p">.</span><span class="nx">getPrice</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.85</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="kd">class</span><span class="w"> </span><span class="nx">GoldUserLevel</span><span class="w"> </span><span class="k">implements</span><span class="w"> </span><span class="nx">IUserLevel</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">getBookPrice</span><span class="p">(</span><span class="nx">book</span><span class="o">:</span><span class="w"> </span><span class="kt">Book</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nx">book</span><span class="p">.</span><span class="nx">getPrice</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.8</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">getEpubPrice</span><span class="p">(</span><span class="nx">epub</span><span class="o">:</span><span class="w"> </span><span class="kt">Epub</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nx">epub</span><span class="p">.</span><span class="nx">getPrice</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.85</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="kd">class</span><span class="w"> </span><span class="nx">PlatinumUserLevel</span><span class="w"> </span><span class="k">implements</span><span class="w"> </span><span class="nx">IUserLevel</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">getBookPrice</span><span class="p">(</span><span class="nx">book</span><span class="o">:</span><span class="w"> </span><span class="kt">Book</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nx">book</span><span class="p">.</span><span class="nx">getPrice</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.75</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="nx">getEpubPrice</span><span class="p">(</span><span class="nx">epub</span><span class="o">:</span><span class="w"> </span><span class="kt">Epub</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="nx">epub</span><span class="p">.</span><span class="nx">getPrice</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">0.8</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">getBookPrice</span><span class="p">(</span><span class="nx">user</span><span class="o">:</span><span class="w"> </span><span class="kt">IUser</span><span class="p">,</span><span class="w"> </span><span class="nx">book</span><span class="o">:</span><span class="w"> </span><span class="kt">Book</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="nx">level</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">user</span><span class="p">.</span><span class="nx">getUserLevel</span><span class="p">()</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">level</span><span class="p">.</span><span class="nx">getBookPrice</span><span class="p">(</span><span class="nx">book</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">getEpubPrice</span><span class="p">(</span><span class="nx">user</span><span class="o">:</span><span class="w"> </span><span class="kt">IUser</span><span class="p">,</span><span class="w"> </span><span class="nx">epub</span><span class="o">:</span><span class="w"> </span><span class="kt">Epub</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="nx">level</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">user</span><span class="p">.</span><span class="nx">getUserLevel</span><span class="p">()</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">level</span><span class="p">.</span><span class="nx">getEpubPrice</span><span class="p">(</span><span class="nx">epub</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div></code></pre></div>
</div>
<p><a href="https://github.com/jkyochen/readable-about-if-else-for/blob/main/if-else-polymorphism/refactoring/example1.ts">完整代码参考</a> / <a href="https://github.com/jkyochen/readable-about-if-else-for/blob/main/if-else-polymorphism/refactoring/example1.js">js 版本</a></p>
<h3>小结</h3>
<ol>
<li>嵌套和 else 都是一种坏味道，能不写就不写。</li>
<li>这种快速返回的处理方法叫卫语句，一般把容易处理的情况快速返回达到减少分支的目的，从而最后可以无嵌套的处理正常情况。</li>
<li>重复的 if/else 可以通过多态屏蔽重复的代码。实现上通过接口屏蔽细节，在需要使用的时候根据类型传入相应的接口实现，从而让使用方不需要关系这些不同的类型。</li>
</ol>
<h2>for</h2>
<h3>例子一</h3>
<p>for 循环的问题是代码是过程式的，需要人脑一个元素一个元素的取出来去跑函数体，我们可以通过 map filter reduce 的写法达到声明式效果，只需要告诉程式要做什么而不是怎么做。</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">toParameters</span><span class="p">(</span><span class="nx">chapters</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="nx">parameters</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[];</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">const</span><span class="w"> </span><span class="nx">chapter</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="nx">chapters</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">chapter</span><span class="p">.</span><span class="nx">isApproved</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">            </span><span class="nx">parameters</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">toChapterParameter</span><span class="p">(</span><span class="nx">chapter</span><span class="p">));</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">parameters</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div></code></pre></div>
</div>
<p>通过 filter map 重构后：</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">toParameters</span><span class="p">(</span><span class="nx">chapters</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">chapters</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">chapter</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">chapter</span><span class="p">.</span><span class="nx">isApproved</span><span class="p">())</span><span class="w"></span>
</div><div class="line"><span class="w">        </span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">chapter</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">toChapterParameter</span><span class="p">(</span><span class="nx">chapter</span><span class="p">));</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div></code></pre></div>
</div>
<h3>例子二</h3>
<p>还有经常可以看到的代码是，一个循环里面做了太多的事情。</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="kd">let</span><span class="w"> </span><span class="nx">averageAge</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="kd">let</span><span class="w"> </span><span class="nx">totalSalary</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">const</span><span class="w"> </span><span class="nx">p</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="nx">people</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">  </span><span class="nx">averageAge</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">p</span><span class="p">.</span><span class="nx">age</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="w">  </span><span class="nx">totalSalary</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">p</span><span class="p">.</span><span class="nx">salary</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="nx">averageAge</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">averageAge</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nx">people</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span><span class="w"></span>
</div></code></pre></div>
</div>
<p>一般我们会把 for 循环里面做的不同的事情拆到不同的函数中去，这里例子在这里不太好，不过这不是我们的最终版本。</p>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="kd">let</span><span class="w"> </span><span class="nx">averageAge</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="kd">let</span><span class="w"> </span><span class="nx">totalSalary</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">const</span><span class="w"> </span><span class="nx">p</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="nx">people</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">  </span><span class="nx">averageAge</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">calAverageAge</span><span class="p">(</span><span class="nx">p</span><span class="p">.</span><span class="nx">age</span><span class="p">,</span><span class="w"> </span><span class="nx">averageAge</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="w">  </span><span class="nx">totalSalary</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">calTotalSalary</span><span class="p">(</span><span class="nx">p</span><span class="p">.</span><span class="nx">salary</span><span class="p">,</span><span class="w"> </span><span class="nx">totalSalary</span><span class="p">);</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">calAverageAge</span><span class="p">(</span><span class="nx">age</span><span class="p">,</span><span class="w"> </span><span class="nx">totalAge</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">age</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">totalAge</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="kd">function</span><span class="w"> </span><span class="nx">calTotalSalary</span><span class="p">(</span><span class="nx">salary</span><span class="p">,</span><span class="w"> </span><span class="nx">totalSalary</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">salary</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">totalSalary</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="nx">averageAge</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">averageAge</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nx">people</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span><span class="w"></span>
</div></code></pre></div>
</div>
<p>有一个在大家看来比较激进的做法，用两个 for 循环去做这两件事，大家会担心性能的问题。有几个观点可以和大家讨论下。</p>
<ol>
<li>性能瓶颈是压测出来的，在一开始开发的时候，可以把可读性放到性能的前面。</li>
<li>函数拆小后，可以提高可读性，一个函数只做一件事。</li>
<li>函数拆小后，可以提供更高的复用性。</li>
</ol>
<div class="block-code" data-language="js"><div class="highlight"><pre><span></span><code><div class="line"><span class="kd">let</span><span class="w"> </span><span class="nx">totalSalary</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">const</span><span class="w"> </span><span class="nx">p</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="nx">people</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">  </span><span class="nx">totalSalary</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">p</span><span class="p">.</span><span class="nx">salary</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line">
</div><div class="line"><span class="kd">let</span><span class="w"> </span><span class="nx">averageAge</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">const</span><span class="w"> </span><span class="nx">p</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="nx">people</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
</div><div class="line"><span class="w">  </span><span class="nx">averageAge</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">p</span><span class="p">.</span><span class="nx">age</span><span class="p">;</span><span class="w"></span>
</div><div class="line"><span class="p">}</span><span class="w"></span>
</div><div class="line"><span class="nx">averageAge</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">averageAge</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nx">people</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span><span class="w"></span>
</div></code></pre></div>
</div>
<h3>小结</h3>
<ol>
<li>通过一些基本的函数式函数 map filter reduce 来简化 for 循环，从而达到声明式写法的简洁。</li>
<li>过程式是描述怎么做，声明式是描述做什么，抽象层级更高。</li>
<li>某些情况我们可以拆分循环函数，把函数拆小，让函数只做一件事，因为只有小函数才有更有可能去复用。</li>
</ol>
<h2>总结</h2>
<ol>
<li>我们可以通过卫语句，多态，声明式编程，降低代码的复杂度，提高的代码的可读性和可维护性。</li>
<li>有一个方式可以计算一个函数的复杂度，叫做圈复杂度 <a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity">Cyclomatic complexity</a>。我们可以通过一些工具来检查代码是否有复杂度太高的函数。<ol>
<li><a href="https://eslint.org/docs/rules/complexity#complexity">Javascript ESLint</a></li>
<li><a href="https://checkstyle.sourceforge.io/config_metrics.html#CyclomaticComplexity">Java Checkstyle</a></li>
</ol>
</li>
<li>更多例子可以参考 <a href="https://github.com/jkyochen/readable-about-if-else-for">Github 地址</a>。</li>
</ol>
<h2>References</h2>
<ol>
<li><a href="https://book.douban.com/subject/30468597/">重构（第2版）</a><ol>
<li>以卫语句取代嵌套的条件表达式 <a href="https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html">Replace Nested Conditional with Guard Clauses</a></li>
<li>以多态取代条件表达式 <a href="https://refactoring.com/catalog/replaceConditionalWithPolymorphism.html">Replace Conditional with Polymorphism</a></li>
<li>以管道取代循环 <a href="https://refactoring.com/catalog/replaceLoopWithPipeline.html">Replace Loop with Pipeline</a></li>
<li>拆分循环 <a href="https://refactoring.com/catalog/splitLoop.html">Split Loop</a></li>
</ol>
</li>
<li><a href="https://refactoring.com/catalog/">Refactoring Catalog</a></li>
<li><a href="https://time.geekbang.org/column/intro/100068401">代码之丑</a></li>
<li><a href="https://coolshell.cn/articles/17757.html">如何重构“箭头型”代码</a></li>
<li><a href="http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy">编程的智慧</a></li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Nginx Too many open files]]></title><guid>https://czq.me/posts/nginx-too-many-open-files-41359714</guid><link>https://czq.me/posts/nginx-too-many-open-files-41359714</link><pubDate>Sat, 15 Jan 2022 14:22:00 +0000</pubDate><content:encoded><![CDATA[<p>工作中遇到两次 Nginx 报 24: Too many open files，每次都给业务带来一些损失，记录一下。</p>
<h2>问题</h2>
<p>报错原因是达到句柄限制，一般是 Nginx 配置问题。</p>
<h2>解决方案</h2>
<h3>1. 系统句柄设置</h3>
<div class="block-code" data-language="md"><div class="highlight"><pre><span></span><code><div class="line"><span class="gh"># /etc/security/limits.conf</span>
</div></code></pre></div>
</div>
<h3>2. /etc/nginx/nginx.conf</h3>
<div class="block-code" data-language="md"><div class="highlight"><pre><span></span><code><div class="line"><span class="gh"># worker_rlimit_nofile 30000;</span>
</div><div class="line"><span class="gh"># https://nginx.org/en/docs/ngx_core_module.html#worker_rlimit_nofile</span>
</div></code></pre></div>
</div>
<h3>3. 使用 Systemd 管理的进程需要额外的设置进程的句柄数量</h3>
<div class="block-code" data-language="md"><div class="highlight"><pre><span></span><code><div class="line"><span class="gh"># /etc/systemd/system/nginx.service</span>
</div><div class="line"><span class="gh"># LimitNOFILE=500000</span>
</div></code></pre></div>
</div>
<h2>References</h2>
<p><a href="https://www.claudiokuenzler.com/blog/850/nginx-socket-failed-24-too-many-open-files">Nginx socket() failed (24: Too many open files)</a></p>
]]></content:encoded></item><item><title><![CDATA[使用 nrm 来切换 npm 源]]></title><guid>https://czq.me/posts/shi-yong-nrm-lai-qie-huan-npm-yuan-7b832376</guid><link>https://czq.me/posts/shi-yong-nrm-lai-qie-huan-npm-yuan-7b832376</link><pubDate>Sat, 03 Jul 2021 03:06:00 +0000</pubDate><content:encoded><![CDATA[<p>一般公司都会自建 npm 源，而在家使用公司的源需要连接 VPN，非常的麻烦。</p>
<p>之前在第三极的时候使用 <a href="https://github.com/Pana/nrm">nrm</a> 来切换 npm 源，非常方便。记录一下，我的老年人记忆。</p>
<h2>新增源</h2>
<div class="block-code" data-language="sh"><div class="highlight"><pre><span></span><code><div class="line">nrm add example https://registry.npm.example.com
</div></code></pre></div>
</div>
<h2>查看所有源</h2>
<div class="block-code" data-language="sh"><div class="highlight"><pre><span></span><code><div class="line">nrm ls
</div></code></pre></div>
</div>
<h2>对所有所有源测速</h2>
<div class="block-code" data-language="sh"><div class="highlight"><pre><span></span><code><div class="line">nrm <span class="nb">test</span>
</div></code></pre></div>
</div>
]]></content:encoded></item><item><title><![CDATA[Filco 键盘连接指南]]></title><guid>https://czq.me/posts/filco-keyboard-bluetooth-connect-guide</guid><link>https://czq.me/posts/filco-keyboard-bluetooth-connect-guide</link><pubDate>Sat, 12 Jun 2021 15:24:00 +0000</pubDate><content:encoded><![CDATA[<p>每次使用 Filco 键盘的时候就忘记如何进行蓝牙连接，记录一下。</p>
<h2>概念</h2>
<h3>切换设备快捷键</h3>
<ol>
<li>同时按下 Ctrl + Alt + Fn，然后松开，再立刻按 1 ~ 4，代表了当前在用指定数字的蓝牙通道连接设备。</li>
<li>注意点。<ol>
<li>Ctrl 使用键盘自带换过键位的需要使用换过之后的键位。</li>
<li>Alt 使用电脑换键的需要使用原有的键位。</li>
</ol>
</li>
</ol>
<h3>闪烁灯</h3>
<ol>
<li>在切换到通道后，如果蓝灯慢速闪烁 10 秒，说明原来的通道已经占用。</li>
<li>蓝灯快闪 60 秒，说明正在等待配对。</li>
</ol>
<h3>复位键</h3>
<p>键盘背面的复位按键，是清除当前蓝牙通道连接的设备，让当前通道进入配对状态。而不是把所有四个通道都清除。</p>
<h2>连接</h2>
<ol>
<li>切换到制定通道。<ol>
<li>蓝灯慢闪 10 秒，就按一下键盘背后的复位键。</li>
<li>蓝灯快闪 60 秒，则可以连接。</li>
</ol>
</li>
<li>连接电脑，输入 PIN 码即可连接。</li>
</ol>
<h2>切换设备</h2>
<ol>
<li>切换设备之前需要关闭之前连接设备的蓝牙。</li>
<li>随机敲键后，就自动连接上另一台设备。</li>
</ol>
<h2>Windows 系统连接不同点</h2>
<p>当需要在电脑上输入 PIN 码时，则需要进行如下步骤即可完成连接。</p>
<ol>
<li>在原本已经连接的键盘上输入六位任意 PIN 码。</li>
<li>接着在需要连接的键盘上重复输入上面的六位 PIN 码。</li>
</ol>
<h2>References</h2>
<p><a href="https://v2ex.com/t/441562">v2ex.com</a></p>
]]></content:encoded></item><item><title><![CDATA[言论自由和审查的边界]]></title><guid>https://czq.me/posts/yan-lun-zi-you-he-shen-cha-de-bian-jie-dc238b5e</guid><link>https://czq.me/posts/yan-lun-zi-you-he-shen-cha-de-bian-jie-dc238b5e</link><pubDate>Sun, 28 Feb 2021 12:33:00 +0000</pubDate><content:encoded><![CDATA[<p>仲裁者需要对自己审查的权利加以限制，尊重被仲裁者的言论自由的权利。</p>
<h2><a href="https://en.wikipedia.org/wiki/Freedom_of_speech">言论自由</a></h2>
<p>根据 WIKI 的定义，「言论自由是一项原则，它支持个人或社区自由地表达自己的观点和思想，而不必担心遭到报复、审查或法律制裁。」。</p>
<p>言论自由的前提还是要尊重他人的基本权利。任何传播儿童色情，恐怖分子等行为并不是言论自由，他破坏人类底线的，是需要进行审查的。</p>
<h2><a href="https://en.wikipedia.org/wiki/Censorship">审查</a></h2>
<p>根据 WIKI 的定义，「审查制度，通常指某些政府机构、新闻媒体和其他控制机构对被认为是有害的、敏感的、或是不合适的演讲及其他公共言论的抑制。」。</p>
<p>在这个语境下的审查是偏贬义词的，掌权者为了保证权利的稳定，对民众过滤掉对政权有影响的信息。在这种情况下，一些大型企业为了活下去，进行自我审查，由于标准不一致，导致了不同网站的尺度不一的现象。</p>
<p>可是带来的问题是，这些机构的权利太大了，名义上的审查和实际的审查时有出入的，审查的边界由于国家政治和法律的不同控制在机构和政府这个两个主体身上。</p>
<h2>边界</h2>
<p>借由特朗普被 Twitter 永久封杀的事件，我在 Twitter 观察到有两类说法，一类是违反了言论自由，一类是和言论自由无关。</p>
<h3>主张特朗普是政府机构不受言论自由保护</h3>
<p>「希望延伸談一下言論自由。很多人以為推特封川普的號是對言論自由的侵犯。這是錯誤的。美國憲法的目的是要保護私人不受政府侵犯，其所賦予的言論自由即第一修正案是說政府不得制定法律侵犯言論等自由也是指私人的走疲，川普之所以有眾多受眾是因為他是政治領導人而不是私人，其公開言論為非私人性質」</p>
<p><a href="https://twitter.com/64_heishan/status/1347746523551997952">Source</a></p>
<h3>主张特朗普有言论自由</h3>
<p>「大多数人对于言论自由的含义并不理解，言论自由是人权部分，同时是说出与你不同观点的权利，无论以何种方式封锁审查言论都是对人的天赋权利的伤害，也自然是对公权的伤害。推特脸书的卑劣举动无非如此，走到这一步，不堪入目。」</p>
<p><a href="https://twitter.com/aiww/status/1347307781234323462?s=12">Source</a></p>
<p>「问题是推特脸书扮演了仲裁者的角色，叛离言论自由的社会价值公约，这些个公司已是今天的意识形态隐形政府，为资本国家政府和权利做不到的事儿作打手，其他所谓主流媒体亦如此。如此行为标志西方社会的道德价值沦丧以及资本主义的体制性绝症。」</p>
<p><a href="https://twitter.com/aiww/status/1347437500541894656?s=12">Source</a></p>
<h2>结尾</h2>
<p>这里有几个疑问：</p>
<ol>
<li>政府机构有没有言论自由的权利？</li>
<li>特朗普到底是仲裁者还是被仲裁者？</li>
</ol>
<p>虽然我无法回答上面的问题，但是有一点我是确认的，仲裁者需要对自己审查的权利加以限制，尊重被仲裁者的言论自由的权利。</p>
]]></content:encoded></item><item><title><![CDATA[耗子叔的技术学习模版]]></title><guid>https://czq.me/posts/hao-zi-shu-de-ji-zhu-xue-xi-mo-ban-b802e934</guid><link>https://czq.me/posts/hao-zi-shu-de-ji-zhu-xue-xi-mo-ban-b802e934</link><pubDate>Mon, 20 Jul 2020 15:08:00 +0000</pubDate><content:encoded><![CDATA[<p>技术和生活一样，都存在大量选择需要 trade-off，不同的场景，不同的人，选择都不一样。刨根问底是我们解决问题的重要手段。</p>
<h2>历史</h2>
<ol>
<li>这个技术出现的背景、初衷。</li>
<li>要达到什么样的目标或是要解决什么样的问题。</li>
</ol>
<h2>优缺点</h2>
<ol>
<li>这个技术的优势和劣势分别是什么，或者说这个技术的 trade-off 是什么。（要什么和不要什么）</li>
</ol>
<h2>场景</h2>
<ol>
<li>这个技术适用的场景。<ol>
<li>业务场景。</li>
<li>技术场景。</li>
</ol>
</li>
</ol>
<h2>架构</h2>
<ol>
<li>技术的组成部分和关键点。</li>
</ol>
<h2>原理</h2>
<ol>
<li>技术的底层原理和关键实现。</li>
</ol>
<h2>对比</h2>
<ol>
<li>已有的实现和它之间的对比。</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[浏览器打开 Google.com 中涉及的 DNS 查找]]></title><guid>https://czq.me/posts/liu-lan-qi-da-kai-google-com-zhong-she-ji-de-dns-04d89ab7</guid><link>https://czq.me/posts/liu-lan-qi-da-kai-google-com-zhong-she-ji-de-dns-04d89ab7</link><pubDate>Sun, 29 Mar 2020 05:54:00 +0000</pubDate><content:encoded><![CDATA[<p>缓存无处不在。</p>
<h2>DNS 查询路径</h2>
<ol>
<li>从浏览起缓存里找。</li>
<li>从系统缓存里找。</li>
<li>从系统 Host 里找。</li>
<li>从系统配置的 DNS 服务器缓存找。<ol>
<li>使用路由器提供的公共 DNS。</li>
<li>使用用户自己修改的公共 DNS。</li>
<li>使用运营商提供的 Local DNS。</li>
</ol>
</li>
<li>转发 DNS。如果本地缓存没有相应的域名结果，将查询请求转发给另外一台 DNS 服务器。</li>
<li>递归 DNS。从根域名 “.” 服务器，顶级域名服务器（“.com”），一级域名服务器（“google.com”）等一级一级递归查询，直到最终找到权威服务器取得结果。</li>
</ol>
<h2>浏览器缓存</h2>
<h3>Firefox(v74.0)</h3>
<p><code>about:config</code> 中的相关设置是 <code>network.dnsCacheEntries</code> 和 <code>network.dnsCacheExpiration</code>，默认都是 60s。</p>
<h3>Chrome(v80.0.3987.149)</h3>
<p>关于 Chrome DNS 缓存多久，没有找到具体的来源。这个问题 <a href="https://stackoverflow.com/questions/36917513/how-long-google-chrome-and-firefox-cache-dns-records">how-long-google-chrome-and-firefox-cache-dns-records</a> 说是 60s。</p>
<p><code>chrome://net-internals/#dns</code> 可以清理缓存。</p>
<h2>系统缓存</h2>
<p>本地系统的缓存通常是 1 小时，根据与 DNS 记录关联的 TTL，本地解析 DNS 服务器的缓存可以运行数天。</p>
<p><a href="https://web.archive.org/web/20150206054041/http://www.binbert.com/blog/2009/12/default-time-to-live-ttl-values/">Default Time To Live (TTL) values</a></p>
<p><a href="https://stackoverflow.com/a/17757735/7275527">关于各个系统如何清理 DNS</a></p>
]]></content:encoded></item><item><title><![CDATA[读 Go 调度系列的笔记]]></title><guid>https://czq.me/posts/du-go-diao-du-xi-lie-de-bi-ji-1f3d3e52</guid><link>https://czq.me/posts/du-go-diao-du-xi-lie-de-bi-ji-1f3d3e52</link><pubDate>Tue, 17 Mar 2020 16:31:00 +0000</pubDate><content:encoded><![CDATA[<p>Golang 自己维护线程池来对接 Goroutine，降低系统的调度成本。</p>
<h2>程序性能差的原因</h2>
<ol>
<li>线程处于 Waiting 状态。由于等待硬件（disk, network）操作系统（system calls）同步调用（atomic, mutexes）导致线程处于 Waiting 状态。</li>
<li>Context Switching。大量的线程处在 Runnable 状态争抢时间片导致的 Context Switching。</li>
<li>Cache-Coherency problem。由于每个核心都有 Cache Lines 的副本（3～40个时钟周期），并行运行的多个线程读写相同或相邻的 Cache Lines 数据时，会导致脏页的产生，进而导致其他线程读写时需要去主存储器访问（100〜300个时钟周期）才能获取缓存行的新副本。</li>
</ol>
<h2>调度名词</h2>
<p><strong>P(Processor)</strong> logical processors</p>
<p><strong>M(Machine)</strong> OS Thread</p>
<p><strong>G(Goroutine)</strong> application-level threads</p>
<p><strong>GRQ</strong> Global Run Queue</p>
<p><strong>LRQ</strong> Local Run Queue</p>
<h2>允许调度器做出调度决策的事件</h2>
<ol>
<li>go 关键字</li>
<li>Garbage collection</li>
<li>System calls</li>
<li>Synchronization and Orchestration</li>
</ol>
<h2>如何调度来保证程序性能</h2>
<p>协作式调度（Cooperating Scheduler）</p>
<h3>一, 通过轮询器进行异步系统调用</h3>
<ol>
<li>通过使用网络轮询器（network poller）进行网络系统调用，调度程序可以防止 Goroutine 在进行这些系统调用时阻止 M。 这有助于使 M 保持可用以执行 P 的 LRQ 中的其他 Goroutine，而无需创建新的 M。这有助于减少 OS 上的调度负载。</li>
<li>其次把该 Goroutine 移回 该 P 的 LRQ 中。</li>
</ol>
<h3>二, 通过分离 M 和 P 进行同步系统调用</h3>
<ol>
<li>调度程序能够识别 Goroutine-1 导致 M 阻塞。 此时，调度程序将 M1 与 P 分离，而阻塞 Goroutine-1 仍然处于连接状态。 然后，调度程序引入一个新的 M2 来为 P 服务。此时，可以从 LRQ 中选择 Goroutine-2，并在 M2 上进行上下文切换。</li>
<li>Goroutine-1 完成了阻塞系统调用。此时，Goroutine-1 可以移回 LRQ 并再次由 P 提供服务。将 M1 放在一边以备将来使用。</li>
</ol>
<h3>三, 窃取工作（Work Stealing）</h3>
<ol>
<li>P1 没有更多的 Goroutines 要执行，P1 需要检查 P2 在其 LRQ 中是否有 Goroutines，并取它找到的一半。</li>
<li>P2 完成了所有工作。首先，它将查看 P1 的 LRQ，但找不到任何 Goroutine。 接下来，将查看 GRQ。</li>
</ol>
<h2>编写并发程序需要考虑的问题</h2>
<ol>
<li>确定工作负载是否适合并发</li>
<li>确定必须使用正确语义的工作负载类型（CPU-Bound / IO-Bound）非常重要。</li>
</ol>
<h2>References</h2>
<p><a href="https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part1.html">Scheduling In Go : Part I - OS Scheduler</a> ｜ <a href="http://archive.vn/DcOZk">Archive</a></p>
<p><a href="https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part2.html">Scheduling In Go : Part II - Go Scheduler</a> ｜ <a href="http://archive.vn/EftZ1">Archive</a></p>
<p><a href="https://www.ardanlabs.com/blog/2018/12/scheduling-in-go-part3.html">Scheduling In Go : Part III - Concurrency</a> ｜ <a href="http://archive.vn/2P9oG">Archive</a></p>
]]></content:encoded></item><item><title><![CDATA[看见]]></title><guid>https://czq.me/posts/sight</guid><link>https://czq.me/posts/sight</link><pubDate>Tue, 13 Oct 2015 07:34:00 +0000</pubDate><content:encoded><![CDATA[<p>柴静的«看见»是本好书，我不止一次在文章中看到别人推荐，我看了，我也推荐下真本好书，所以我打算读第二遍。书中一个观点让我非常的感同身受，很多坏人比如那些偷东西的孩子，比如那个在镜头下虐待猫的女人，其实他们每个人内心都不坏，可为什么还要去做这些事呢，是社会的问题？还是家庭的问题？还是什么呢，请看书。
验证了我的什么观点呢，一个人有坏的一面，也有好的一面，这个观点我一直在验证，尽管有的人表面上很凶，但是我坚信ta们有柔软的一面，比如对子女，对爱人，对父母。</p>
<p>P14</p>
<div class="blockquote"><blockquote><p>白岩松有天安慰我：“人们声称的最美好的岁月其实都是最痛苦的，只是事后回忆起&gt; 来的时候才那么幸福。”</p>
</blockquote></div>
<p>P25</p>
<div class="blockquote"><blockquote><p>当一个人关心别人的时候，才会忘记自己。</p>
</blockquote></div>
<p>P31</p>
<div class="blockquote"><blockquote><p>人们还能笑的时候，是不容易被打败的。</p>
</blockquote></div>
<p>P33</p>
<div class="blockquote"><blockquote><p>只问耕耘，不问收获。</p>
</blockquote></div>
<p>P47</p>
<div class="blockquote"><blockquote><p>后来我长大一点儿了，就明白了，人总是要分开的，但有的东西永远在的，就像课本&gt; 上那句话，'天涯若比邻'。</p>
</blockquote></div>
<p>P50</p>
<div class="blockquote"><blockquote><p>她能理解人。听别人说话的人。</p>
</blockquote></div>
<p>P53</p>
<div class="blockquote"><blockquote><p>他这么做对么？不，先别回答，你要像苏联作家说的那样，'在清水里呛呛，血水里&gt; 泡泡，咸水里滚滚'，十年之后咱们再来讨论。</p>
</blockquote></div>
<p>P83</p>
<div class="blockquote"><blockquote><p>知道和感觉到，是两回事。</p>
</blockquote></div>
<p>P94</p>
<div class="blockquote"><blockquote><p>苏东坡的诗，“庐山烟雨浙江潮，未到千般恨不消。到得还来别无事，庐山烟雨浙江&gt; 潮。”</p>
</blockquote></div>
<p>P95</p>
<div class="blockquote"><blockquote><p>生和死，苦难与苍老，都蕴含在每一个人的体内，总有一天我们会与之遭逢。我们终&gt; 将浑然难分，像水溶于水中。</p>
</blockquote></div>
<p>P105</p>
<div class="blockquote"><blockquote><p>他笑的时候……他给你一个微笑的时候，简直就像把世界都给了你的那种感觉。</p>
</blockquote></div>
<p>P115</p>
<div class="blockquote"><blockquote><p>我要记得，我当时为什么要这个男人。</p>
</blockquote></div>
<p>P115</p>
<div class="blockquote"><blockquote><p>人是一样的，对幸福的愿望一样，对自身完整的需要一样，只要她生在这儿，这么活&gt; 着，我来到那儿，那么活着，都是偶然。</p>
</blockquote></div>
<p>P115</p>
<div class="blockquote"><blockquote><p>万物流变，千百万年，谁都是一小粒，嵌在世界的秩序当中，采访是什么？采访是生&gt; 命间的往来，认识自己越深，认识他人越深，反之亦然。</p>
</blockquote></div>
<p>P115</p>
<div class="blockquote"><blockquote><p>他人经受的，我必经受。</p>
</blockquote></div>
<p>P117</p>
<div class="blockquote"><blockquote><p>海子有句诗，深得我心：“天空一无所有，为何给我安慰。”</p>
</blockquote></div>
<p>P139</p>
<div class="blockquote"><blockquote><p>我要把他们拖上战场，我不一定能赢，但我会让他们觉得痛，让他们害怕有十几二十&gt; 几个像我这样的人站出来，让他们因为害怕而迅速改变。</p>
</blockquote></div>
<p>很多句子只有在那个故事里才能感受到那种力量，就像上面那句说的<code>知道和感觉到，是两回事。</code></p>
<p>未完待续...</p>
]]></content:encoded></item></channel></rss>