<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Zex</title>
    <description>The latest articles on DEV Community by Zex (@zex).</description>
    <link>https://dev.to/zex</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F170425%2F526ca5cf-b53d-4e0d-be9d-c7ac425cbf74.jpg</url>
      <title>DEV Community: Zex</title>
      <link>https://dev.to/zex</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zex"/>
    <language>en</language>
    <item>
      <title>Back from Africa， AMA</title>
      <dc:creator>Zex</dc:creator>
      <pubDate>Tue, 15 Oct 2019 00:48:48 +0000</pubDate>
      <link>https://dev.to/zex/back-from-africa-ama-254m</link>
      <guid>https://dev.to/zex/back-from-africa-ama-254m</guid>
      <description>&lt;p&gt;Finally, I made my way to Africa. The major purpose for this trip was safaris and to meet my favorite, cheetah. It's aweeeeeeeesome.💪&lt;/p&gt;

&lt;p&gt;Ask anything that comes to you mind 😆&lt;/p&gt;

</description>
      <category>ama</category>
    </item>
    <item>
      <title>SLI, SLO, and SLA</title>
      <dc:creator>Zex</dc:creator>
      <pubDate>Sun, 25 Aug 2019 11:39:26 +0000</pubDate>
      <link>https://dev.to/zex/sli-slo-and-sla-12bp</link>
      <guid>https://dev.to/zex/sli-slo-and-sla-12bp</guid>
      <description>&lt;h3&gt;
  
  
  SLI - Service Level Indicator
&lt;/h3&gt;

&lt;p&gt;Defines a measure of service level provided by service providers.&lt;br&gt;
Examples&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uptime of the service&lt;/li&gt;
&lt;li&gt;Number of Transactions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SLO - Service Level Objective
&lt;/h3&gt;

&lt;p&gt;Defines a target value or a target range of service level, measured by SLI.&lt;br&gt;
Examples&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Availability of the service should be 99.999%&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SLA - Service Level Agreement
&lt;/h3&gt;

&lt;p&gt;Defines a commitment between service providers and customers.&lt;br&gt;
Examples&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refund service fee&lt;/li&gt;
&lt;li&gt;Provide free service for a period of time&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Nines
&lt;/h3&gt;

&lt;p&gt;Percentages to measure the service. &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Availability %&lt;/th&gt;
&lt;th&gt;Downtime per year&lt;/th&gt;
&lt;th&gt;Downtime per month&lt;/th&gt;
&lt;th&gt;Downtime per week&lt;/th&gt;
&lt;th&gt;Downtime per day&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;55.5555555% ("nine fives")&lt;/td&gt;
&lt;td&gt;162.33 days&lt;/td&gt;
&lt;td&gt;13.53 days&lt;/td&gt;
&lt;td&gt;74.92 hours&lt;/td&gt;
&lt;td&gt;10.67 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;90% ("one nine")&lt;/td&gt;
&lt;td&gt;36.53 days&lt;/td&gt;
&lt;td&gt;73.05 hours&lt;/td&gt;
&lt;td&gt;16.80 hours&lt;/td&gt;
&lt;td&gt;2.40 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;95% ("one nine five")&lt;/td&gt;
&lt;td&gt;18.26 days&lt;/td&gt;
&lt;td&gt;36.53 hours&lt;/td&gt;
&lt;td&gt;8.40 hours&lt;/td&gt;
&lt;td&gt;1.20 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;97%&lt;/td&gt;
&lt;td&gt;10.96 days&lt;/td&gt;
&lt;td&gt;21.92 hours&lt;/td&gt;
&lt;td&gt;5.04 hours&lt;/td&gt;
&lt;td&gt;43.20 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;98%&lt;/td&gt;
&lt;td&gt;7.31 days&lt;/td&gt;
&lt;td&gt;14.61 hours&lt;/td&gt;
&lt;td&gt;3.36 hours&lt;/td&gt;
&lt;td&gt;28.80 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99% ("two nines")&lt;/td&gt;
&lt;td&gt;3.65 days&lt;/td&gt;
&lt;td&gt;7.31 hours&lt;/td&gt;
&lt;td&gt;1.68 hours&lt;/td&gt;
&lt;td&gt;14.40 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.5% ("two nines five")&lt;/td&gt;
&lt;td&gt;1.83 days&lt;/td&gt;
&lt;td&gt;3.65 hours&lt;/td&gt;
&lt;td&gt;50.40 minutes&lt;/td&gt;
&lt;td&gt;7.20 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.8%&lt;/td&gt;
&lt;td&gt;17.53 hours&lt;/td&gt;
&lt;td&gt;87.66 minutes&lt;/td&gt;
&lt;td&gt;20.16 minutes&lt;/td&gt;
&lt;td&gt;2.88 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.9% ("three nines")&lt;/td&gt;
&lt;td&gt;8.77 hours&lt;/td&gt;
&lt;td&gt;43.83 minutes&lt;/td&gt;
&lt;td&gt;10.08 minutes&lt;/td&gt;
&lt;td&gt;1.44 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.95% ("three nines five")&lt;/td&gt;
&lt;td&gt;4.38 hours&lt;/td&gt;
&lt;td&gt;21.92 minutes&lt;/td&gt;
&lt;td&gt;5.04 minutes&lt;/td&gt;
&lt;td&gt;43.20 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.99% ("four nines")&lt;/td&gt;
&lt;td&gt;52.60 minutes&lt;/td&gt;
&lt;td&gt;4.38 minutes&lt;/td&gt;
&lt;td&gt;1.01 minutes&lt;/td&gt;
&lt;td&gt;8.64 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.995% ("four nines five")&lt;/td&gt;
&lt;td&gt;26.30 minutes&lt;/td&gt;
&lt;td&gt;2.19 minutes&lt;/td&gt;
&lt;td&gt;30.24 seconds&lt;/td&gt;
&lt;td&gt;4.32 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.999% ("five nines")&lt;/td&gt;
&lt;td&gt;5.26 minutes&lt;/td&gt;
&lt;td&gt;26.30 seconds&lt;/td&gt;
&lt;td&gt;6.05 seconds&lt;/td&gt;
&lt;td&gt;864.00 milliseconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.9999% ("six nines")&lt;/td&gt;
&lt;td&gt;31.56 seconds&lt;/td&gt;
&lt;td&gt;2.63 seconds&lt;/td&gt;
&lt;td&gt;604.80 milliseconds&lt;/td&gt;
&lt;td&gt;86.40 milliseconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.99999% ("seven nines")&lt;/td&gt;
&lt;td&gt;3.16 seconds&lt;/td&gt;
&lt;td&gt;262.98 milliseconds&lt;/td&gt;
&lt;td&gt;60.48 milliseconds&lt;/td&gt;
&lt;td&gt;8.64 milliseconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.999999% ("eight nines")&lt;/td&gt;
&lt;td&gt;315.58 milliseconds&lt;/td&gt;
&lt;td&gt;26.30 milliseconds&lt;/td&gt;
&lt;td&gt;6.05 milliseconds&lt;/td&gt;
&lt;td&gt;864.00 microseconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99.9999999% ("nine nines")&lt;/td&gt;
&lt;td&gt;31.56 milliseconds&lt;/td&gt;
&lt;td&gt;2.63 milliseconds&lt;/td&gt;
&lt;td&gt;604.80 microseconds&lt;/td&gt;
&lt;td&gt;86.40 microseconds&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Source: &lt;a href="https://en.wikipedia.org/wiki/High_availability"&gt;Wiki&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>sre</category>
    </item>
    <item>
      <title>Hold My Emoji</title>
      <dc:creator>Zex</dc:creator>
      <pubDate>Mon, 12 Aug 2019 14:33:39 +0000</pubDate>
      <link>https://dev.to/zex/hold-my-emoji-acc</link>
      <guid>https://dev.to/zex/hold-my-emoji-acc</guid>
      <description>&lt;p&gt;Let's create a random emoji generator in &lt;code&gt;package emoji&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Prepare a list of funny emoji codes &lt;/p&gt;

&lt;p&gt;🚲 🐸 🐡 🎉 😆 👏 🏄 🔞 🍫 🏖️ 🐳 💯 🤓 🌝 🤘 🤣 🍪 🌼 🔔 🎅 🍄 🚗 🦄 🎃 👈 :trollface: 🐒 🌞 :octocat: 👇 🐽 🛍️ 🍼 :feelsgood: 🍻 🙀 👀 ☃️ 🐣 🚀 🐮 💅 ‼️ 🚁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;AvailEmojies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;":bike:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":frog:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":blowfish:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":tada:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":laughing:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":clap:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":surfer:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":underage:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":chocolate_bar:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":beach_umbrella:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":whale:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":100:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":nerd_face:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":full_moon_with_face:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":metal:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":rofl:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":cookie:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":blossom:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":bell:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":santa:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":mushroom:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":red_car:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":unicorn:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":jack_o_lantern:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":point_left:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":trollface:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":monkey:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":sun_with_face:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":octocat:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":point_down:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":pig_nose:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":shopping:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":baby_bottle:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":feelsgood:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":beers:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":scream_cat:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":eyes:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":snowman_with_snow:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":hatching_chick:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":rocket:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":cow:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":nail_care:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":bangbang:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;":helicopter:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Prepare a helper function to generate a code every time being called. Using a random integer generation function in &lt;code&gt;math/rand&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;RndEmoji&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;AvailEmojies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UnixNano&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Intn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AvailEmojies&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Almost done, for now, you can use it somewhere else for fun. Here I'd like to use the test feature provided by &lt;code&gt;go&lt;/code&gt;.&lt;br&gt;
Now, create a test file with suffix &lt;code&gt;_test&lt;/code&gt; in the same location as emoji.go, called &lt;code&gt;emoji_test.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s"&gt;"testing"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestEmoji&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RndEmoji&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Simple. Isn't it?&lt;br&gt;
To run the test just &lt;code&gt;go test&lt;/code&gt; it, use verbose mode to allow &lt;code&gt;Log&lt;/code&gt; level info to print.&lt;br&gt;
   &lt;code&gt;go test -v &amp;lt;GOPATH&amp;gt;/holdmyemoji&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;===&lt;/span&gt; RUN   TestEmoji
&lt;span class="nt"&gt;---&lt;/span&gt; PASS: TestEmoji &lt;span class="o"&gt;(&lt;/span&gt;0.01s&lt;span class="o"&gt;)&lt;/span&gt;
    emoji_test.go:9: :whale:
    emoji_test.go:9: :unicorn:
    emoji_test.go:9: :metal:
    emoji_test.go:9: :octocat:
    emoji_test.go:9: :monkey:
    emoji_test.go:9: :sun_with_face:
    emoji_test.go:9: :nail_care:
    emoji_test.go:9: :helicopter:
    emoji_test.go:9: :unicorn:
    emoji_test.go:9: :bell:
PASS
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The test can also be built first by &lt;code&gt;go test &amp;lt;GOPATH&amp;gt;/rndemoji -c -o emoji&lt;/code&gt;, then you can run &lt;code&gt;./emoji -test.v&lt;/code&gt; multiple times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;===&lt;/span&gt; RUN   TestEmoji
&lt;span class="nt"&gt;---&lt;/span&gt; PASS: TestEmoji &lt;span class="o"&gt;(&lt;/span&gt;0.01s&lt;span class="o"&gt;)&lt;/span&gt;
    emoji_test.go:9: :santa:
    emoji_test.go:9: :tada:
    emoji_test.go:9: :pig_nose:
    emoji_test.go:9: :rocket:
    emoji_test.go:9: :eyes:
    emoji_test.go:9: :full_moon_with_face:
    emoji_test.go:9: :100:
    emoji_test.go:9: :trollface:
    emoji_test.go:9: :pig_nose:
    emoji_test.go:9: :bangbang:
PASS
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Also, to have more fun, shuffle the list every time before generating, the list changes from time to time. It, of course, will cost more computation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;AvailEmojies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UnixNano&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Intn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;AvailEmojies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;AvailEmojies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AvailEmojies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;AvailEmojies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;Use your funny list, play with it 🚀&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>algorithms</category>
      <category>go</category>
      <category>testing</category>
    </item>
    <item>
      <title>Something About Grok</title>
      <dc:creator>Zex</dc:creator>
      <pubDate>Sun, 11 Aug 2019 08:15:11 +0000</pubDate>
      <link>https://dev.to/zex/something-about-grok-4ih4</link>
      <guid>https://dev.to/zex/something-about-grok-4ih4</guid>
      <description>&lt;p&gt;Here Grok, a filter plugin used in ELK stack. It converts unstructured logs to structured ones.&lt;/p&gt;

&lt;p&gt;Grok is built upon regular expression. The syntax is &lt;code&gt;%{SYNTAX:SEMANTIC}&lt;/code&gt;. For example:&lt;/p&gt;

&lt;p&gt;A log line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.0.1.13 GET /home HTTP/2.0 200 13969
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A filter defined in logstash configure file as below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;filter {
  grok {
    match =&amp;gt; {
      "message" =&amp;gt; '%{IPORHOST:ip} \"%{WORD:method} %{DATA:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response:int} (?:-|%{NUMBER:bytes:int})'
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The log line passes through the filter, it produces the result&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ip: 10.0.1.13
method: GET
request: /home
response: 200
bytes: 13969

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With structured data, you can search by specific field while using Elasticsearch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Grok Debugger
&lt;/h2&gt;

&lt;p&gt;If you are not so sure the pattern would work on your log or not, here are some grok debugger to help you verify the patterns.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grokdebug.herokuapp.com"&gt;Grok Debugger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grokconstructor.appspot.com/do/match"&gt;Test Grok Patterns&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make log processing easier. :D&lt;/p&gt;

&lt;h2&gt;
  
  
  See also
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://logz.io/blog/5-logstash-filter-plugins"&gt;5 Logstash Filter Plugins&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/kkos/oniguruma"&gt;Oniguruma&lt;/a&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;The Jargon File, which describes itself as a "Hacker's Dictionary" and has been published under that name three times, puts grok in a programming context:&lt;/p&gt;

&lt;p&gt;When you claim to "grok" some knowledge or technique, you are asserting that you have not merely learned it in a detached instrumental way but that it has become part of you, part of your identity. For example, to say that you "know" Lisp is simply to assert that you can code in it if necessary — but to say you "grok" LISP is to claim that you have deeply entered the world-view and spirit of the language, with the implication that it has transformed your view of programming. Contrast zen, which is a similar supernatural understanding experienced as a single brief flash.&lt;br&gt;
--Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>elasticsearch</category>
      <category>backend</category>
      <category>devops</category>
      <category>dataanalysis</category>
    </item>
    <item>
      <title>What books are you reading recently?</title>
      <dc:creator>Zex</dc:creator>
      <pubDate>Sun, 04 Aug 2019 14:41:08 +0000</pubDate>
      <link>https://dev.to/zex/what-books-are-you-reading-recently-4nh1</link>
      <guid>https://dev.to/zex/what-books-are-you-reading-recently-4nh1</guid>
      <description>

</description>
      <category>discuss</category>
      <category>reading</category>
    </item>
    <item>
      <title>Brainstorm: Some Thoughts About User Behavior Tracking
</title>
      <dc:creator>Zex</dc:creator>
      <pubDate>Mon, 22 Jul 2019 15:46:57 +0000</pubDate>
      <link>https://dev.to/zex/brainstorm-some-thought-about-user-behavior-tracking-29p1</link>
      <guid>https://dev.to/zex/brainstorm-some-thought-about-user-behavior-tracking-29p1</guid>
      <description>&lt;p&gt;👉&lt;em&gt;Remain on high level&lt;/em&gt;&lt;br&gt;
👉&lt;em&gt;No specific tools/frameworks included&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters👈
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Understand your users better&lt;/li&gt;
&lt;li&gt;Narrow the gap between how you expect user to use and how user actually use it&lt;/li&gt;
&lt;li&gt;Marketing data analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to do it👇
&lt;/h2&gt;

&lt;h3&gt;
  
  
  On client side
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sync, send and wait&lt;/li&gt;
&lt;li&gt;Async, send and go&lt;/li&gt;
&lt;li&gt;Send in business components&lt;/li&gt;
&lt;li&gt;Send in a separate service&lt;/li&gt;
&lt;li&gt;Keep a local cache for unsent events for resend later&lt;/li&gt;
&lt;li&gt;Local cache size limitation&lt;/li&gt;
&lt;li&gt;API call timeout/failure handling&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  On server side
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Log collection, centralize all log from all backend servers&lt;/li&gt;
&lt;li&gt;Generate an event based on predefined event data structure on request&lt;/li&gt;
&lt;li&gt;Direct to database&lt;/li&gt;
&lt;li&gt;Publish over message queue&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Employ a third-party service
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Direct request&lt;/li&gt;
&lt;li&gt;Integrate SDK&lt;/li&gt;
&lt;li&gt;Shared database/separate database&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Data definition☝️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Event
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;EventType, what happened&lt;/li&gt;
&lt;li&gt;CreatedAt, when did it happen&lt;/li&gt;
&lt;li&gt;Source, where did it happen&lt;/li&gt;
&lt;li&gt;Payload, who/what was involved&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Result
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;StatusCode&lt;/li&gt;
&lt;li&gt;StatusMessage&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  API🌻
&lt;/h2&gt;

&lt;h3&gt;
  
  
  create
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Create(Event) Result&lt;/code&gt;&lt;/p&gt;

</description>
      <category>hld</category>
      <category>architecture</category>
      <category>design</category>
    </item>
    <item>
      <title>Evil DFS: How To Successfully Distract Yourself</title>
      <dc:creator>Zex</dc:creator>
      <pubDate>Thu, 18 Jul 2019 01:20:02 +0000</pubDate>
      <link>https://dev.to/zex/evil-dfs-how-to-successfully-distract-yourself-583m</link>
      <guid>https://dev.to/zex/evil-dfs-how-to-successfully-distract-yourself-583m</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Reading link1&lt;/li&gt;
&lt;li&gt;Found interesting link2&lt;/li&gt;
&lt;li&gt;Go to link2&lt;/li&gt;
&lt;li&gt;Read &amp;amp; found interesting link3&lt;/li&gt;
&lt;li&gt;Go to link3&lt;/li&gt;
&lt;li&gt;Read &amp;amp; found interesting link4&lt;/li&gt;
&lt;li&gt;Go to link4&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;li&gt;No more interesting link&lt;/li&gt;
&lt;li&gt;Exit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ok, this is DFS.&lt;/p&gt;

&lt;p&gt;For some pages simply constructed with interesting links, it goes this path&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For link1..n read&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;BFS is evil too. If it happened to include DFS cases 🙃 a day is over.&lt;/p&gt;

&lt;p&gt;Pros: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn many by starting with one&lt;/li&gt;
&lt;li&gt;Satisfy curiosity&lt;/li&gt;
&lt;li&gt;Collect some topics for next time meet a nerd 🤓&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time-consuming  ｡ﾟ( ﾟஇ‸இﾟ)ﾟ｡&lt;/li&gt;
&lt;li&gt;Possibly forget what was about to do&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...Wait, that sounds like human web crawler 🤔&lt;/p&gt;

&lt;p&gt;Here are some links for practice&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;a href="https://redis.io/topics/sentinel"&gt;redis sentinel&lt;/a&gt;&lt;br&gt;
-&amp;gt; &lt;a href="https://github.com/soundcloud/roshi"&gt;roshi on github&lt;/a&gt;&lt;br&gt;
-&amp;gt; &lt;a href="http://book.mixu.net"&gt;mixu's book&lt;/a&gt;&lt;br&gt;
-&amp;gt; &lt;a href="https://military.wikia.org/wiki/Finnish_Defence_Forces"&gt;Finnish Defence Forces&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OK, let's talk about another how-to.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to break the loop before it is too late
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Just open the links in another new tab without switching to them. This is easy to achieve by configure the browser or by right-click option. Supported by most browsers.&lt;/li&gt;
&lt;li&gt;Keep a to-do list in whatever format that you like. I also use &lt;a href="https://trello.com"&gt;Trello&lt;/a&gt;. A list of interesting papers can also be found at my Github page. Check it out if interested.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hopefully this help you be more productive😃&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Play With Mattermost</title>
      <dc:creator>Zex</dc:creator>
      <pubDate>Mon, 15 Jul 2019 14:06:06 +0000</pubDate>
      <link>https://dev.to/zex/play-with-mattermost-3k16</link>
      <guid>https://dev.to/zex/play-with-mattermost-3k16</guid>
      <description>&lt;p&gt;Mattermost provides a series of API to interact with the server.&lt;/p&gt;

&lt;p&gt;Let's create a service to post Mattermost message daily if we have new orders.&lt;/p&gt;

&lt;p&gt;The new order message contains a plaintext message and an Excel file, which is generated by the service as well.&lt;/p&gt;

&lt;p&gt;The message contains Emoji, just include them as plaintext.&lt;/p&gt;

&lt;p&gt;We have new orders today!! 👏👏&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"We have new orders today!! :clap::clap:"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Upload the file first so that the post can include it by adding the file ID. &lt;code&gt;data&lt;/code&gt; is the file content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;frsp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cli&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UploadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chann_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Great! Now the file IDs are in &lt;code&gt;frsp&lt;/code&gt;, which is a &lt;code&gt;FileUploadResponse&lt;/code&gt;. Extract them and save in &lt;code&gt;file_ids&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;  &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rsp&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cli&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreatePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;FileIds&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;file_ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ChannelId&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;chann_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then we have a new post on the channel with &lt;code&gt;chann_id&lt;/code&gt;, members on that channel can see it. :D&lt;/p&gt;

&lt;h2&gt;
  
  
  See also
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mattermost/mattermost-server"&gt;Mattermost Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mattermost.com"&gt;Mattermost&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://api.mattermost.com/#tag/bots"&gt;Bots API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>team</category>
      <category>go</category>
      <category>api</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Homebrew Performance Evaluator</title>
      <dc:creator>Zex</dc:creator>
      <pubDate>Mon, 08 Jul 2019 14:52:19 +0000</pubDate>
      <link>https://dev.to/zex/homebrew-performance-evaluator-ng8</link>
      <guid>https://dev.to/zex/homebrew-performance-evaluator-ng8</guid>
      <description>&lt;p&gt;Performance improvement is life-long work. First of all, you need to know how it does right now. The way to do it usually depends on the scale.&lt;/p&gt;

&lt;p&gt;Developed a distributed performance test system before with Python, which took quite a long time to evolve and it's complicated. I wanted to try something different in this brand new project. Before introducing all kinds of performance test framework, I would like to make a simple and handy application.&lt;/p&gt;

&lt;p&gt;There we Go.&lt;/p&gt;

&lt;p&gt;Keep in mind: simple and handy.&lt;/p&gt;

&lt;p&gt;Then it shall be able to &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send requests to API server&lt;/li&gt;
&lt;li&gt;Evaluate the time cost&lt;/li&gt;
&lt;li&gt;Generate some reports&lt;/li&gt;
&lt;li&gt;Cookie support&lt;/li&gt;
&lt;li&gt;Configure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Evaluator&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Evaluator struct {
  cli *http.Client
  report []Item
  cookie *Cookie
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Item&lt;/code&gt; to keep the request results&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Item struct {
  Url *url.URL `json:"url,omitempty"`
  Elapsed time.Duration `json:"elapsed,omitempty"`
  CreatedAt time.Time `json:"created_at,omitempty"`
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Cookie&lt;/code&gt; to keep session-related data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Cookie struct {
  data map[string]interface{}
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Get some data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (self *Evaluator) Elapsed(req *http.Request) (*http.Response, error) {
  before := time.Now()
  rsp, err := self.cli.Do(req)
  self.report = append(self.report, Item{
    Url: req.URL,
    Elapsed: time.Now().Sub(before),
    CreatedAt: before,
  })
  return rsp, err
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Time to print some results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (self *Evaluator) GenReport() error {
  fmt.Println()
  fmt.Println("-- report --")
  for _, v := range self.report {
    fmt.Println(v.String())
  }
  return nil
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To get a pretty print, create a &lt;code&gt;String&lt;/code&gt; function for &lt;code&gt;Item&lt;/code&gt; as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (self Item) String() string {
  return fmt.Sprintf("%v [%s:%v] %s", self.CreatedAt.Unix(), self.Url.Path, self.Url.RawQuery, self.Elapsed.String())
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Maybe generate some CSV for further processing. I was using pretty print in Go, good to read but difficult to process later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (self *Evaluator) GenReportCSV(path string) error {
  // ...
  w := csv.NewWriter(fd)
  w.Write([]string{"Timestamp", "Api", "Query", "Elapsed"})
  for _, v := range self.report {
    if err = w.Write([]string{
        fmt.Sprintf("%d", v.CreatedAt.Unix()),
        v.Url.Path,
        fmt.Sprintf("%s", v.Url.RawQuery),
        fmt.Sprintf("%.4f", v.Elapsed.Seconds())});
      err != nil {
        return err
      }
  }
  w.Flush()
  return nil
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Create a dummy client to do something crazy, &lt;code&gt;wg&lt;/code&gt; is a &lt;code&gt;WaitGroup&lt;/code&gt;&lt;br&gt;
 variable to wait for all crazy clients to finish their operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func dummy_terminal() {
  app := apps.NewApp()
  defer app.Close()

  // ... do something crazy to API ...

  if err := app.GenReport(); err != nil {
    fmt.Println("generate report failed: ", err)
  }

  out := fmt.Sprintf("%s/performance-%d.csv", *output_base, time.Now().UnixNano())
  if err := app.GenReportCSV(out); err != nil {
    fmt.Println("generate report csv failed: ", err)
  }
  wg.Done()
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Configure in command line with &lt;code&gt;flag&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var(
  terminals   = flag.Int("terminals", 30, "total concurrent terminals")
  output_base = flag.String("output_base", "/tmp", "backend output_base")
)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Found a great logging module in Fabric :D&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get github.com/hyperledger/fabric/common/flogging
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The CSV output looks like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Timestamp,Api,Query,Elapsed
1562142836,/api/home,,2.0599
1562142842,/api/list,,0.0311
1562142842,/api/somepage,id=99,0.0323
1562142842,/api/somepage,id=66,1.6131
1562142845,/api/somepage,id=33,0.0432

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The console output is pretty much the same, except the time is formatted.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>go</category>
      <category>api</category>
      <category>backend</category>
    </item>
    <item>
      <title>How Did I Recover From An Alcohol Party And Get Back To Work The Next Day</title>
      <dc:creator>Zex</dc:creator>
      <pubDate>Sun, 30 Jun 2019 06:29:14 +0000</pubDate>
      <link>https://dev.to/zex/how-did-i-recover-from-an-alcohol-party-and-get-back-to-work-the-next-day-32pd</link>
      <guid>https://dev.to/zex/how-did-i-recover-from-an-alcohol-party-and-get-back-to-work-the-next-day-32pd</guid>
      <description>&lt;p&gt;Even though I know I should not drink too much, sometimes I would just leave all the rules behind and enjoy the party.&lt;/p&gt;

&lt;p&gt;So now what? I need to recover from that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Soup
&lt;/h2&gt;

&lt;p&gt;Usually, I have muffins and coffee for breakfast. In the morning after the party night, those are the last thing I want. The only thing came to my mind is soup.&lt;/p&gt;

&lt;p&gt;Soup is easier to digest and absorb, provides nutrition, energy and water.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sports &amp;amp; Energy Drink
&lt;/h2&gt;

&lt;p&gt;Water is crucial to clean up the waste and residual alcohol in the body, but pure water is not enough. I need something to wake up my tongue. &lt;/p&gt;

&lt;p&gt;Sports drink to supply the body inorganic salt, vitamins as well as water, also taste good.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vitamin Supplements
&lt;/h2&gt;

&lt;p&gt;I have some vitamin supplements with me, just took some as usual.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sleep
&lt;/h2&gt;

&lt;p&gt;Alcohol genuinely helps sleep, so no worry about it. Just get a comfortable place the body knows what to do.&lt;/p&gt;

&lt;p&gt;Work hard and don't forget to have fun. Overdrinking alcohol is not encouraged still.🐒&lt;/p&gt;

</description>
      <category>work</category>
      <category>life</category>
      <category>health</category>
    </item>
    <item>
      <title>Mini-Program, FTW?</title>
      <dc:creator>Zex</dc:creator>
      <pubDate>Sun, 23 Jun 2019 03:16:30 +0000</pubDate>
      <link>https://dev.to/zex/mini-program-ftw-2ikd</link>
      <guid>https://dev.to/zex/mini-program-ftw-2ikd</guid>
      <description>&lt;p&gt;If you haven't experienced WeChat you might not hear of mini-program. It's a sub-application in WeChat ecosystem.&lt;/p&gt;

&lt;p&gt;In 90% of the time I work on backend development, mini program development is new to me, just got my hands on it this week.&lt;/p&gt;

&lt;p&gt;Here is McDonald's order mini program.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fxqvrrc0gwjnaifkfw8sg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fxqvrrc0gwjnaifkfw8sg.png" alt="Order McDonald's"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A mini-program can be developed on Mac or Windows as the toolkits are available for only these two.&lt;/p&gt;

&lt;p&gt;It usually contains &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WXML, defines how the UI looks like.&lt;/li&gt;
&lt;li&gt;WXSS, WeChat style sheet.&lt;/li&gt;
&lt;li&gt;JS/TS, defines business logic.&lt;/li&gt;
&lt;li&gt;Configs, define how it should run.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Similar to Web UI project except it uses some WeChat defined tags and API. Comparing to native apps, it's more lightweight. Check out the reference &lt;a href="https://mp.weixin.qq.com/cgi-bin/wx" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, the documents have poor globalization support. Most of the documents are originally written in Chinese. Well, they are improving it, English version can be found &lt;a href="https://open.wechat.com/cgi-bin/newreadtemplate?t=overseas_open/docs/mini-programs/development/framework/view/wxss#view_wxss" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Interested? Try it out🙃&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Let's Talk About Garbage</title>
      <dc:creator>Zex</dc:creator>
      <pubDate>Sun, 16 Jun 2019 05:36:11 +0000</pubDate>
      <link>https://dev.to/zex/let-s-talk-about-garbage-32ec</link>
      <guid>https://dev.to/zex/let-s-talk-about-garbage-32ec</guid>
      <description>&lt;p&gt;Our city is seriously working on waste classification which is good for resource recycling and environmental protection.🐒 All waste must be dumped into the right place. Since July 1st, those&lt;br&gt;
individuals don't obey the regulations could be fined up to 200RMB, for organizations could be up to 500K RMB.😢&lt;/p&gt;
&lt;h3&gt;
  
  
  Resource Management
&lt;/h3&gt;

&lt;p&gt;Good developers borrow resource from the system and release them when work is done. But human being is lazy animal, so languages that "automatically" recycle the waste are created. Therefore, developers can focus on their business without bothering the resource stuff.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;C++&lt;/em&gt; doesn't have language level garbage collection due to implementation difficulties and performance consideration. A set of &lt;strong&gt;smart pointers&lt;/strong&gt; are created as part of STL to serve the resource management purpose.&lt;/p&gt;

&lt;p&gt;Languages like &lt;em&gt;Java&lt;/em&gt;, &lt;em&gt;Go&lt;/em&gt;, &lt;em&gt;Python&lt;/em&gt; and &lt;em&gt;JavaScript&lt;/em&gt;, performs GC automatically.&lt;/p&gt;
&lt;h2&gt;
  
  
  GC Techniques
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Reference Counting
&lt;/h3&gt;

&lt;p&gt;Maintains a counter for each object to denote references to this object. When an object is not referenced by anyone it would be freed. This leads to cyclic reference issue, meaning when two objects are referenced by each other, neither of them could be freed eventually.&lt;/p&gt;

&lt;p&gt;Here come a workaround called &lt;strong&gt;weak reference&lt;/strong&gt;, which doesn't protect the referenced object being recycled. It doesn't increase the reference count for the referent object.&lt;/p&gt;
&lt;h3&gt;
  
  
  Mark and Sweep
&lt;/h3&gt;

&lt;p&gt;As a tracing garbage collector, it contains two stages: mark stage and sweep stage. &lt;/p&gt;

&lt;p&gt;First of all the garbage collector walk through the objects graph from the root, find out those reachable objects and set the mark bit to 1, which is 0 by default.&lt;/p&gt;

&lt;p&gt;Secondly, scans all the objects, recycle those unreachable (marked as 0), set the mark bit of those reachable to 1. &lt;/p&gt;

&lt;p&gt;The downside of this method is it stops the program execution for quite a while.&lt;/p&gt;
&lt;h3&gt;
  
  
  Tri-Colour
&lt;/h3&gt;

&lt;p&gt;It uses three colours, white, grey and black to differentiate states of objects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The white set contains candidates to recycle.&lt;/li&gt;
&lt;li&gt;The grey set contains objects that reachable from the root and have references to objects in the white set. &lt;/li&gt;
&lt;li&gt;The black set contains objects that reachable from the root, have no reference to objects in the white set and aren't candidates to recycle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Objects can only be moved from grey to black and from white to grey.&lt;/p&gt;

&lt;p&gt;The algorithm is demonstrated as below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
While grey set not empty:
  Pick an object from a grey set
  Move the object to black set
  Move white objects it references to grey set

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It ensures that no black objects are referencing white objects, which are not reachable from the root and can be recycled once the grey set is empty. It can work on the fly without suspending the system for a period of time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stop the World
&lt;/h3&gt;

&lt;p&gt;The garbage collector comes with a&lt;br&gt;
recycle threshold when closed or reached, a recycle happened. &lt;/p&gt;

&lt;p&gt;It stops the program execution until the garbage collection is done. This brings high throughput for GC. It's suitable for non-interactive applications. By stopping the world for a noticeable period of time with a specific frequency it introduces performance issue as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Incremental GC
&lt;/h3&gt;

&lt;p&gt;Performs garbage collection discretely by breaking the collection into pieces of processes and completes them one by one. Instead of freezing for a long time like &lt;em&gt;STW&lt;/em&gt; does, it breaks it down to many tiny periods of time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concurrent GC
&lt;/h3&gt;

&lt;p&gt;It runs garbage collection concurrently without stopping the world. Minimizing the pause time makes it a good choice for interactive programs. Low throughout makes it costs longer time to complete GC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Garbage Collection in Languages
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GC in Python
&lt;/h3&gt;

&lt;p&gt;The  &lt;em&gt;gc&lt;/em&gt; module in Python allows you to interact with the GC system. It could be disabled by &lt;code&gt;gc.disable()&lt;/code&gt; and manually GC by invoking &lt;code&gt;gc.collect()&lt;/code&gt;. &lt;code&gt;gc.garbage&lt;/code&gt; is a list of objects to be collected.&lt;/p&gt;

&lt;p&gt;Interested in learning more about it? Check &lt;a href="https://rushter.com/blog/python-garbage-collector/"&gt;this&lt;/a&gt; out.😎&lt;/p&gt;

&lt;h3&gt;
  
  
  GC in Go
&lt;/h3&gt;

&lt;p&gt;Go allows you to disable GC by running the application with &lt;code&gt;GOGC=off&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Go comes with two knobs to control the GC. The first one is GCPercent. Basically this is a knob that adjusts how much CPU you want to use and how much memory you want to use. The default is 100 which means that half the heap is dedicated to live memory and half the heap is dedicated to allocation. You can modify this in either direction.&lt;/p&gt;

&lt;p&gt;MaxHeap, which is not yet released but is being used and evaluated internally, lets the programmer set what the maximum heap size should be. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Learn more about the Go garbage collector from source code &lt;a href="https://github.com/golang/go/blob/master/src/runtime/mgc.go"&gt;mgc&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  GC in JavaScript
&lt;/h3&gt;

&lt;p&gt;GC in Javascript is based on  &lt;strong&gt;reachability&lt;/strong&gt; and completely automatic. Found this &lt;a href="https://javascript.info/garbage-collection"&gt;article&lt;/a&gt; explains it very well, I recommend you read through it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Helpful Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals"&gt;Fundamentals of Garbage Collection&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.m.wikipedia.org/wiki/Garbage_collection_(computer_science)"&gt;Wiki:Garbage Collection&lt;/a&gt;&lt;/p&gt;

</description>
      <category>garbagecollection</category>
      <category>memorymanagement</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
