<?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: jguo</title>
    <description>The latest articles on DEV Community by jguo (@jiayanguo).</description>
    <link>https://dev.to/jiayanguo</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%2F378278%2F23c6da96-e885-44dc-b2d3-3a97363c8638.jpeg</url>
      <title>DEV Community: jguo</title>
      <link>https://dev.to/jiayanguo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jiayanguo"/>
    <language>en</language>
    <item>
      <title>Interview With Facebook</title>
      <dc:creator>jguo</dc:creator>
      <pubDate>Tue, 11 Jan 2022 03:26:06 +0000</pubDate>
      <link>https://dev.to/jiayanguo/interview-with-facebook-5h46</link>
      <guid>https://dev.to/jiayanguo/interview-with-facebook-5h46</guid>
      <description>&lt;h1&gt;
  
  
  Round 1 Interview
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Introduce your most challenging project in last 12 months.&lt;/li&gt;
&lt;li&gt;Coding.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://leetcode.com/problems/binary-search-tree-iterator/"&gt;https://leetcode.com/problems/binary-search-tree-iterator/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://leetcode.com/problems/k-closest-points-to-origin/"&gt;https://leetcode.com/problems/k-closest-points-to-origin/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The coding questions are pretty simple actually, I was not doing that good. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Build a template Dockerfile with ONBUILD</title>
      <dc:creator>jguo</dc:creator>
      <pubDate>Sat, 13 Nov 2021 19:25:45 +0000</pubDate>
      <link>https://dev.to/jiayanguo/build-a-template-dockerfile-with-onbuild-il</link>
      <guid>https://dev.to/jiayanguo/build-a-template-dockerfile-with-onbuild-il</guid>
      <description>&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;Industry Dockerfile usually is far more complicated than a demo, most time, we need to build our own base image. What if you want to run some common steps in a child Dockerfile? For example, all children docker images must run a setup.sh script. Here how &lt;code&gt;ONBUILD&lt;/code&gt; instruction can help.&lt;/p&gt;

&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;Let's define a base image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM openjdk:16-alpine3.13

WORKDIR /app

ONBUILD COPY ./setup.sh .
ONBUILD RUN ./setup.sh
ONBUILD COPY src ./src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let build the base image&lt;br&gt;
&lt;code&gt;docker build -t my-base-image&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, let see how the child image looks like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM my-base-image:latest

WORKDIR /app

CMD ["./mvnw", "spring-boot:run"]

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

&lt;/div&gt;



&lt;p&gt;From the example, you can see, we have a much tiny child image. More important, we have a common pattern across all children images. For example, if child image is missing &lt;code&gt;setup.sh&lt;/code&gt;, the build will fail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Note
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ONBUILD&lt;/code&gt; instruction is not inherited by “grand-children” builds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/engine/reference/builder/#onbuild"&gt;https://docs.docker.com/engine/reference/builder/#onbuild&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
    </item>
    <item>
      <title>Why isn't the hashcode of a java object  consistent on different hosts</title>
      <dc:creator>jguo</dc:creator>
      <pubDate>Sat, 15 May 2021 05:30:52 +0000</pubDate>
      <link>https://dev.to/jiayanguo/why-isn-t-the-hashcode-of-a-java-object-consistent-on-different-hosts-me9</link>
      <guid>https://dev.to/jiayanguo/why-isn-t-the-hashcode-of-a-java-object-consistent-on-different-hosts-me9</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;Recently, one of our API customers complains that the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag"&gt;etag&lt;/a&gt; of our API is not working correctly. So, I started checking what's wrong. And what I found was that the etag across different hosts is not consistent. So, the etag is a hex string of java object hashcode. In the beginning, I had no idea what's wrong. Since the other APIs are working, only one of the API is not. So, I wrote a simple test code that prints each field on the object. Finally, I found the hashcode of java enum is different on different hosts. So why?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;I just googled the question and found this &lt;a href="https://madhead.me/posts/enums-fuckup/"&gt;post&lt;/a&gt;. It is exactly the same issue as I had. &lt;/p&gt;

&lt;p&gt;Let's take a look java enum hashcode definition in the official document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public final int hashCode()
Returns a hash code for this enum constant.
Overrides:
hashCode in class Object
Returns:
a hash code for this enum constant.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See, what the problem is? Here, it says that it returns a hashcode for this enum constant. Enum constant is an object of the enum, and it is constant. So, it is consistent on the JVM. But, each JVM should have its own constant of the enum. That explains my question at the beginning. &lt;strong&gt;Enum’s on different JVMs will have different hash codes.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to resolve the issue?
&lt;/h2&gt;

&lt;p&gt;So, we know what is going on. But, how to resolve it. As you can see, the enum hashcode function is a &lt;code&gt;final&lt;/code&gt; method. So, which means we can't override it. &lt;/p&gt;

&lt;p&gt;This tells us that the only way to override the hashcode is the place where we use the enum object. Let's an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class TestDAO {
  private String test1;
  private Type type;

  enum Type {
    APPLE,
    ORANGE
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's override the hashcode method on TestDAO.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class TestDAO {
  private String id;
  private Type type;

  @Override
  public hashCode(){
    Objects.hashCode(id, type.name());
  }

  @Override
  public equals(){
    ...
  }

  enum Type {
    APPLE,
    ORANGE
  }
}

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

&lt;/div&gt;



&lt;p&gt;Note, the difference is that we use &lt;code&gt;type.name()&lt;/code&gt; instead of the type itself. That resolves the issue. Not perfectly, but, works.&lt;/p&gt;

&lt;p&gt;Reference:&lt;br&gt;
&lt;a href="https://madhead.me/posts/enums-fuckup/"&gt;https://madhead.me/posts/enums-fuckup/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#hashCode()"&gt;https://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#hashCode()&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag"&gt;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>hashcode</category>
    </item>
    <item>
      <title>Host Personal Website (React App) on OCI for Free</title>
      <dc:creator>jguo</dc:creator>
      <pubDate>Sun, 02 May 2021 21:42:28 +0000</pubDate>
      <link>https://dev.to/jiayanguo/host-personal-website-react-app-on-oci-for-free-17c9</link>
      <guid>https://dev.to/jiayanguo/host-personal-website-react-app-on-oci-for-free-17c9</guid>
      <description>&lt;h2&gt;
  
  
  Why OCI?
&lt;/h2&gt;

&lt;p&gt;Free! Free! Always Free. With OCI always free you can do a lot. You can get 2 free VM for free for hosting a &lt;a href="https://blogs.oracle.com/developers/launching-your-own-free-private-vpn-in-the-oracle-cloud" rel="noopener noreferrer"&gt;VPN sever&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Want to build a personal website free? Here how OCI object storage can help. You get 10G object storage for free as long as you sign in an &lt;a href="https://www.oracle.com/cloud/free/" rel="noopener noreferrer"&gt;OCI account&lt;/a&gt;. That is enough for hosting websites as many as you want.&lt;br&gt;
OCI Object storage is not supporting to host website out of box. But, with very minimum work, we can make that magic happen. Let's get started. &lt;/p&gt;
&lt;h2&gt;
  
  
  Create a public visible bucket.
&lt;/h2&gt;

&lt;p&gt;First, create a bucket under object storage.&lt;br&gt;
Second, edit visibility to make it public.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgi3te44mpmxa7xkx36m.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgi3te44mpmxa7xkx36m.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, upload any file to the bucket, and find the URL path. Save your base path for later use. In my case, my base path is "/n/ax5ixupubw30/b/jguo.site/o/";&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkiv8158lcp55b1n98smi.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkiv8158lcp55b1n98smi.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Create a React App.
&lt;/h2&gt;

&lt;p&gt;You can create a react app by following react official &lt;a href="https://github.com/facebook/create-react-app" rel="noopener noreferrer"&gt;document&lt;/a&gt;. This is not a react tutorial, so, I will not go into any more details. You can also copy my personal website source code &lt;a href="https://github.com/jiayanguo/portfolio-site" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Now, let's create a script to fix the base path issue during object storage rendering your website.&lt;br&gt;
(Note: You need to replace &lt;code&gt;/n\/ax5ixupubw30\/b\/jguo\.site\/o\/&lt;/code&gt; with your base path which I mentioned earlier. Also, when you use OCI CLI to upload your website, you need to give a specific content-type, otherwise, it won't work. If you upload through console, you don't need to worry about it.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
set -e

cd build

# modifiy index.html file and make it works in oci object storage.

sed -i .bak 's/"\/manifest\.json"/"\/n\/ax5ixupubw30\/b\/jguo\.site\/o\/manifest\.json"/g' index.html
sed -i .bak 's/"\/icon\.JPG"/"\/n\/ax5ixupubw30\/b\/jguo\.site\/o\/icon\.JPG"/g' index.html
sed -i .bak 's/"\/static\/js\//"\/n\/ax5ixupubw30\/b\/jguo\.site\/o\/static\/js\//g' index.html
sed -i .bak 's/"\/static\/css\//"\/n\/ax5ixupubw30\/b\/jguo\.site\/o\/static\/css\//g' index.html
sed -i .bak 's/"static\/js\/"/"n\/ax5ixupubw30\/b\/jguo\.site\/o\/static\/js\/"/g' index.html

# please setup oci cli first : https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm
oci os object bulk-delete -ns ax5ixupubw30  -bn jguo.site  --prefix static --force
oci os object put -bn jguo.site --file ./manifest.json --content-type application/json --force
oci os object bulk-upload -bn jguo.site --src-dir ./ --content-type text/html --include *.html --overwrite
oci os object bulk-upload -bn jguo.site --src-dir ./ --content-type image/jpeg --include *.JPG --overwrite
oci os object bulk-upload -bn jguo.site --src-dir ./ --content-type text/javascript --include *.js --overwrite
oci os object bulk-upload -bn jguo.site --src-dir ./ --content-type application/pdf --include *.pdf --overwrite
oci os object bulk-upload -bn jguo.site --src-dir ./ --content-type text/css --include *.css --overwrite
oci os object bulk-upload -bn jguo.site --src-dir ./ --content-type text/plain --exclude *.js --exclude *.html --exclude *.JPG --exclude *.pdf --exclude *.css --exclude ./manifest.json --overwrite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, let's add a command to package json, and automate the deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; "scripts": {
    ...,
    "deploy": "npm run build &amp;amp;&amp;amp; ./deploy_to_oci.sh"
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last, let's deploy it to oci object storage (make sure you install and setup oci cli).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, go back to OCI console, and find the URL for the index.html file. Click the URL, you should see your website now.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's more?
&lt;/h2&gt;

&lt;p&gt;You can see my personal website &lt;a href="https://objectstorage.us-phoenix-1.oraclecloud.com/n/ax5ixupubw30/b/jguo.site/o/index.html#/" rel="noopener noreferrer"&gt;here on OCI&lt;/a&gt;&lt;br&gt;
Or, scan this QR code.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqbe2i7yyzkbe7ilxm2o.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqbe2i7yyzkbe7ilxm2o.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My website source code &lt;a href="https://github.com/jiayanguo/portfolio-site" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>oci</category>
      <category>cloudskills</category>
      <category>website</category>
    </item>
    <item>
      <title>Notification Based on Email Content Build on Serverless. </title>
      <dc:creator>jguo</dc:creator>
      <pubDate>Wed, 30 Dec 2020 00:29:22 +0000</pubDate>
      <link>https://dev.to/jiayanguo/send-notification-based-on-email-content-an9</link>
      <guid>https://dev.to/jiayanguo/send-notification-based-on-email-content-an9</guid>
      <description>&lt;h3&gt;
  
  
  About
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://ark-invest.com/"&gt;Ark invest&lt;/a&gt; ETF is a rising star on the stock market. If you subscribe to the ETF trading notifications, you could receive their trading information at the end of each day. But, I don't really want to get all their trading information. I just want to know their new holdings. So, I'd like to build a system to send me notifications only I care about.&lt;/p&gt;

&lt;h3&gt;
  
  
  Desgin
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tktrwuvD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wxcfxkd2b4c77jnfaosp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tktrwuvD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wxcfxkd2b4c77jnfaosp.png" alt="Alt Text" width="880" height="684"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Build the app step by step
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Create a Google Developer App&lt;/strong&gt;&lt;br&gt;
Follow this &lt;a href="https://blog.mailtrap.io/send-emails-with-gmail-api/"&gt;post&lt;/a&gt; to create a Gmail app on google cloud. &lt;br&gt;
Note: choose Desktop Application when you create OAuth token&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Create first Lambda to process email&lt;/strong&gt;&lt;br&gt;
First, let's create a script to get OAuth token for accessing the Gmail app. (client_secret.json is the file which we get from step 1)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import os
from googleapiclient import errors, discovery
from oauth2client import client, tools, file

SCOPES = ['https://mail.google.com/']
def get_credentials():
    wd = os.getcwd()

    # creates credentials with a refresh token
    credential_path = os.path.join(wd,
                                  'credentials_out.json')
    store = file.Storage(credential_path)
    creds = store.get()
    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
        creds = tools.run_flow(flow, store)
    return creds

if __name__ == '__main__':
    get_credentials()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the out file (credentials_out.json), we should be able to find client_id, client_secret, and refresh_token information. &lt;/p&gt;

&lt;p&gt;Second, let's create build the lambda function to process email content. Find source code on &lt;a href="https://github.com/jiayanguo/ark-go-email/blob/master/app.py"&gt;github&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import os
from googleapiclient import errors, discovery
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from email.mime.text import MIMEText
import base64
import re
import requests
from datetime import date, datetime
from pytz import timezone
import boto3
from oauth2client import client, tools, file
import httplib2
from bs4 import BeautifulSoup
import csv

# TODO
# 1. Validate the date of the email.

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://mail.google.com/']
# ARK_INVEST_QUERY="from:ark@arkinvest.com subject:ARK Investment Management Trading Information"
ARK_INVEST_QUERY=os.environ['EMAIL_QUERY']
S3_BUCKET ="ark-fly"
OBJECT_KEY_PATTERN="dailytradingtrans/{today}-trading.csv"
SEND_NOTIFICATION_TO = "guojiayanc@gmail.com"
SENDER = "noreply@arkfly.com"
TEMP_TRADING_CSV_FILE="/tmp/trading.csv"

def main():
  service = login()
  try:
    result = get_messages(service, 'me')
    if 'messages' in result:
      messageId = result['messages'][0]['id']
      data = get_message('me', messageId, service)
      print(data)
      generate_csv(data)
      today = get_date()
      upload_to_s3(OBJECT_KEY_PATTERN.format(today=today))
      delete_massage(service, 'me', messageId)
    else:
      print("No message found!")
  except Exception as error:
    # TODO Sender is not set correctly
    print("ARK Fly processing failed " + str(error))
    message = create_message(SENDER, SEND_NOTIFICATION_TO, "ARK Fly processing failed", str(error))
    send_message(service, 'me', message)

def delete_massage(service, user_id, message_id):
  try:
    message = service.users().messages().delete(userId=user_id, id=message_id).execute()
  except Exception as error:
    raise error

def login():
  try:
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    return discovery.build('gmail', 'v1', http=http, cache_discovery=False)
  except Exception as error:
    print("Log into gmail failed!" + str(error))
    raise error

def get_credentials():
  client_id = os.environ['GMAIL_CLIENT_ID']
  client_secret = os.environ['GMAIL_CLIENT_SECRET']
  refresh_token = os.environ['GMAIL_REFRESH_TOKEN']

  credentials = client.GoogleCredentials(None,
  client_id,
  client_secret,
  refresh_token,
  None,
  "https://accounts.google.com/o/oauth2/token",
  'my-user-agent')

  return credentials

def upload_to_s3(object_name):
  client = boto3.client('s3')
  try:
    response = client.upload_file(TEMP_TRADING_CSV_FILE, S3_BUCKET, object_name)
  except Exception as error:
    raise Exception("faile to upload to s3! " + str(error))

def get_date():
  tz = timezone('EST')
  today = datetime.now(tz).strftime("%Y-%m-%d")
  return today

def get_message(user_id, message_id, service):
  try:
    message = service.users().messages().get(userId=user_id, id=message_id).execute()
    data = ''
    print(message)
    if 'parts' in message['payload']:
      for part in message['payload']['parts']:
        data += base64.urlsafe_b64decode(part['body']['data']).decode("utf-8") + "\n"
    else:
      data += base64.urlsafe_b64decode(message['payload']['body']['data']).decode("utf-8") + "\n"
    return data
  except Exception as error:
    raise error

def generate_csv(data):
  try:
    bs=BeautifulSoup(data, 'html.parser')
    table_body=bs.find('table')
    rows = table_body.find_all('tr')
    csv_rows = []
    for row in rows:
      cols=row.find_all('td')
      cols=[x.text.strip().replace('\r\n', ' ') for x in cols]
      csv_rows.append(cols)
    with open(TEMP_TRADING_CSV_FILE, "w") as f:
      wr = csv.writer(f)
      wr.writerows(csv_rows)
  except Exception as error:
    raise Exception("Today's trading table not found!" + str(error))

def create_message(sender, to, subject, message_text):
  message = MIMEText(message_text)
  message['to'] = to
  message['from'] = sender
  message['subject'] = subject
  raw_message = base64.urlsafe_b64encode(message.as_string().encode("utf-8"))
  return {
    'raw': raw_message.decode("utf-8")
  }

def send_message(service, user_id, message):
  try:
    message = service.users().messages().send(userId=user_id, body=message).execute()
    print('Message Id: %s' % message['id'])
    return message
  except Exception as error:
    print('An error occurred: %s' % error)
    raise error

def get_messages(service, user_id):
  try:
    return service.users().messages().list(userId=user_id, q=ARK_INVEST_QUERY).execute()
  except Exception as error:
    print('An error occurred: %s' % error)
    raise error

# For local test
if __name__ == '__main__':
    main()

def lambda_handler(event, context):
  main()
  return {
    "status":200
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, let's containerize the python code and push it to ecr on aws.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM amazon/aws-lambda-python:3
WORKDIR /var/task/
COPY . ./
RUN pip install -r requirements.txt
CMD [ "app.lambda_handler" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And build a simple script to push the docker image to ecr (change account id to your aws accountid)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/sh
set -e

docker build . -t ark-go-email
docker tag ark-go-email:latest 120400168286.dkr.ecr.us-west-2.amazonaws.com/ark-go-email:latest
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin 120400168286.dkr.ecr.us-west-2.amazonaws.com
docker push 120400168286.dkr.ecr.us-west-2.amazonaws.com/ark-go-email:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create an AWS lambda from docker container image, check this &lt;a href="https://dev.to/jiayanguo/another-milestone-of-aws-lambda-45f3"&gt;post&lt;/a&gt; for how.&lt;br&gt;
Note: we need to create 4 lambda environment variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EMAIL_QUERY=from:ARK Trading Desk &amp;lt;ark@ark-funds.com&amp;gt; subject:ARK Investment Management Trading Information is:unread newer_than:1d
GMAIL_CLIENT_ID=&amp;lt;client_id&amp;gt;
GMAIL_CLIENT_SECRET=&amp;lt;client_secret&amp;gt;
GMAIL_REFRESH_TOKEN=&amp;lt;refresh_token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last, create a cloud watch event to trigger the lambda on cron based.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hDIi0zwT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o189zitqnjoee43s3ll6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hDIi0zwT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o189zitqnjoee43s3ll6.png" alt="Alt Text" width="880" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Create Second Lambda to fetch ark holding information&lt;/strong&gt;&lt;br&gt;
Source code can be found &lt;a href="https://github.com/jiayanguo/ark-fly-ingest"&gt;here&lt;/a&gt;&lt;br&gt;
All the steps should be the same as in section 2. But, the cron express is cron(0 4 ? * TUE-SAT *).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Create Third Lambda to process data generated by section 2 and 3&lt;/strong&gt;&lt;br&gt;
Source code can be found &lt;a href="https://github.com/jiayanguo/ark-fly-processor"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Create Fourth Lambda to send an email notification&lt;/strong&gt;&lt;br&gt;
Source code can be found &lt;a href="https://github.com/jiayanguo/ark-fly-notification"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Setup s3 event notifications&lt;/strong&gt;&lt;br&gt;
Choose the s3 bucket -&amp;gt; Properties -&amp;gt; Event notifications.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2YbgOo5K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/avbble6plya4gj4yb2yt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2YbgOo5K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/avbble6plya4gj4yb2yt.png" alt="Alt Text" width="819" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: In section 2, after it processes the email, it uploads a generated csv to s3. And it should trigger the third lambda in section 4. In section 4, if the lambda finds any new holds, it will upload the data s3, which will trigger the last lambda to send a notification. If no new holdings, do nothing. It will not trigger the last lambda. &lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>python</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Go dependencies management </title>
      <dc:creator>jguo</dc:creator>
      <pubDate>Fri, 15 May 2020 06:26:52 +0000</pubDate>
      <link>https://dev.to/jiayanguo/go-dependencies-management-5dek</link>
      <guid>https://dev.to/jiayanguo/go-dependencies-management-5dek</guid>
      <description>&lt;p&gt;How do you manage your dependencies in go? &lt;/p&gt;

</description>
      <category>go</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Learning Golang 108</title>
      <dc:creator>jguo</dc:creator>
      <pubDate>Sun, 10 May 2020 21:26:05 +0000</pubDate>
      <link>https://dev.to/jiayanguo/learning-golang-108-wrap-up-3i0e</link>
      <guid>https://dev.to/jiayanguo/learning-golang-108-wrap-up-3i0e</guid>
      <description>&lt;p&gt;Here is a list of the go beginner courses.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;course&lt;/th&gt;
&lt;th&gt;about&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/jiayanguo/learning-golang-101-5eg0"&gt;101&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Naming Conventions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/jiayanguo/learning-golang-102-a05"&gt;102&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Control Structures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/jiayanguo/learning-golang-102-2fhk"&gt;103&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Functions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/jiayanguo/learning-golang-104-2ida"&gt;104&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Data Structure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/jiayanguo/learning-golang-105-3kk4"&gt;105&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Structs &amp;amp; Pointers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/jiayanguo/learning-golang-106-1cbl"&gt;106&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Interfaces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://dev.to/jiayanguo/learning-golang-107-g8l"&gt;107&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Routines &amp;amp; Channels&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Package manager.
&lt;/h2&gt;

&lt;p&gt;To see popularity of these tools, click &lt;a href="https://github.com/blindpirate/report-of-build-tools-for-java-and-golang#golang"&gt;here&lt;/a&gt;. &lt;code&gt;make&lt;/code&gt; is the most popular tool. Here is an example.&lt;br&gt;
&lt;code&gt;dep&lt;/code&gt; is a more easy way, &lt;a href="https://golang.github.io/dep/docs/introduction.html"&gt;dep&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   # Go parameters
   GOCMD=go
   GOBUILD=$(GOCMD) build
   GOCLEAN=$(GOCMD) clean
   GOTEST=$(GOCMD) test
   GOGET=$(GOCMD) get
   BINARY_NAME=mybinary

   deps:
      $(GOGET) github.com/kubeless/kubeless/pkg/functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note, make is very picky, if you run issues, make sure you open it in &lt;code&gt;vi&lt;/code&gt;. Then run &lt;code&gt;:%s/^[ ]\+/\t/g&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 dots
&lt;/h2&gt;

&lt;p&gt;3 dots in 4 places&lt;br&gt;
Take a look at this &lt;a href="https://yourbasic.org/golang/three-dots-ellipsis/"&gt;post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are a beginner, I highly recommend this &lt;a href="https://www.udemy.com/course/go-the-complete-developers-guide/learn/lecture/7824514#overview"&gt;Go course&lt;/a&gt; on Udemy.&lt;/p&gt;

&lt;p&gt;Here are some sample &lt;a href="https://github.com/jiayanguo/crashgo"&gt;codes&lt;/a&gt; for this course. &lt;/p&gt;

&lt;p&gt;Happy learning!&lt;/p&gt;

</description>
      <category>go</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Learning Golang 107</title>
      <dc:creator>jguo</dc:creator>
      <pubDate>Sun, 10 May 2020 21:16:32 +0000</pubDate>
      <link>https://dev.to/jiayanguo/learning-golang-107-g8l</link>
      <guid>https://dev.to/jiayanguo/learning-golang-107-g8l</guid>
      <description>&lt;h2&gt;
  
  
  Concurrency
&lt;/h2&gt;

&lt;p&gt;Concurrent programming in many environments is made difficult by the subtleties required to implement correct access to shared variables. Go encourages a different approach in which shared values are passed around on channels and, in fact, never actively shared by separate threads of execution. Only one goroutine has access to the value at any given time. Data races cannot occur, by design.  I think this really makes go so shining.&lt;/p&gt;

&lt;h3&gt;
  
  
  Goroutines
&lt;/h3&gt;

&lt;p&gt;Prefix a function or method call with the go keyword to run the call in a new goroutine. When the call completes, the goroutine exits, silently.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func Announce(message string, delay time.Duration) {
    go func() {
        time.Sleep(delay)
        fmt.Println(message)
    }()  // Note the parentheses - must call the function.
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A channel can allow the launching goroutine to wait for the sort to complete.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;c := make(chan int)  // Allocate a channel.
// Start the sort in a goroutine; when it completes, signal on the channel.
go func() {
    list.Sort()
    c &amp;lt;- 1  // Send a signal; value does not matter.
}()
doSomethingForAWhile()
&amp;lt;-c   // Wait for sort to finish; discard sent value.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Receivers always block until there is data to receive. If the channel is unbuffered, the sender blocks until the receiver has received the value. If the channel has a buffer, the sender blocks only until the value has been copied to the buffer; if the buffer is full, this means waiting until some receiver has retrieved a value.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A buffered channel can be used like a semaphore, for instance to limit throughput. In this example, incoming requests are passed to handle, which sends a value into the channel, processes the request, and then receives a value from the channel to ready the “semaphore” for the next consumer. The capacity of the channel buffer limits the number of simultaneous calls to process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var sem = make(chan int, MaxOutstanding)

func handle(r *Request) {
    sem &amp;lt;- 1    // Wait for active queue to drain.
    process(r)  // May take a long time.
    &amp;lt;-sem       // Done; enable next request to run.
}

func Serve(queue chan *Request) {
    for {
        req := &amp;lt;-queue
        go handle(req)  // Don't wait for handle to finish.
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Channels of channels
&lt;/h3&gt;

&lt;p&gt;One of the most important properties of Go is that a channel is a first-class value that can be allocated and passed around like any other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Request struct {
    args        []int
    f           func([]int) int
    resultChan  chan int
}

func sum(a []int) (s int) {
    for _, v := range a {
        s += v
    }
    return
}

request := &amp;amp;Request{[]int{3, 4, 5}, sum, make(chan int)}
// Send request
clientRequests &amp;lt;- request
// Wait for response.
fmt.Printf("answer: %d\n", &amp;lt;-request.resultChan)

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Function Literals
&lt;/h2&gt;

&lt;p&gt;As lambda in java, Go supports &lt;code&gt;Function Literals&lt;/code&gt;. It is a function without a name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;c := make(chan int)
func(ch chan int) {
    list.Sort()
    ch &amp;lt;- 1  // Send a signal; value does not matter.
}(c)  // the () means call the function.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>go</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Learning Golang 106</title>
      <dc:creator>jguo</dc:creator>
      <pubDate>Sun, 10 May 2020 15:25:06 +0000</pubDate>
      <link>https://dev.to/jiayanguo/learning-golang-106-1cbl</link>
      <guid>https://dev.to/jiayanguo/learning-golang-106-1cbl</guid>
      <description>&lt;h3&gt;
  
  
  Interface
&lt;/h3&gt;

&lt;p&gt;Interfaces are a contract to help us manage types.&lt;br&gt;
define an interface&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type bot interface{
   getGreeting() string
}

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

&lt;/div&gt;



&lt;p&gt;Unlike other languages, you need to implement interface explicit. Go uses implicit implementation. As long as you define the same method, it will automatically implement the interface.&lt;br&gt;
For example, &lt;code&gt;englishBot&lt;/code&gt; and &lt;code&gt;spanishBot&lt;/code&gt; are automatically implemented &lt;code&gt;bot&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import (
    "fmt"
)

type bot interface {
    getGreeting() string
}

type englishBot struct {}
type spanishBot struct {}

func (englishBot) getGreeting()string {
    return "Hello!"
}

func (spanishBot) getGreeting() string {
    return "Hola!"
}

func printGreeting(b bot) {
    fmt.Println(b.getGreeting())
}


func main() {
    eb := englishBot{}
    sb := spanishBot{}

    printGreeting(eb)
    printGreeting(sb)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note, if a interface has multiple functions. To implement the interface, you need to implement all the functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embedding
&lt;/h2&gt;

&lt;p&gt;Go has the ability to “borrow” pieces of an implementation by embedding types within a struct or interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

// ReadWriter is the interface that combines the Reader and Writer interfaces.
type ReadWriter interface {
    Reader
    Writer
}

Or
// ReadWriter stores pointers to a Reader and a Writer.
// It implements io.ReadWriter.
type ReadWriter struct {
    reader *Reader
    writer *Writer
}

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

&lt;/div&gt;



</description>
      <category>go</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Learning Golang 105</title>
      <dc:creator>jguo</dc:creator>
      <pubDate>Sun, 10 May 2020 04:17:03 +0000</pubDate>
      <link>https://dev.to/jiayanguo/learning-golang-105-3kk4</link>
      <guid>https://dev.to/jiayanguo/learning-golang-105-3kk4</guid>
      <description>&lt;h3&gt;
  
  
  Custom Type and Receiver
&lt;/h3&gt;

&lt;p&gt;define a type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type deck []string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;receiver&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun (d deck) print() {
   for i, card := range d {
     fmt.Printf(i, card)
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;call print func&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;d := deck{"card1", "card2"}
d.print()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that adding a receiver to a custom type, it extends the type's functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Type assertions
&lt;/h3&gt;

&lt;p&gt;A type assertion takes an interface value and extracts from it a value of the specified explicit type.&lt;br&gt;
For example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;res, ok := deck.([]string)
if ok {
    fmt.Printf("slice value is: %q\n", res)
} else {
    fmt.Printf("value is not a slice\n")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Structs
&lt;/h3&gt;

&lt;p&gt;define a struct&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type person struct {
  firstName string
  lastName  string
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;declare a struct&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// alex := person{"Alex", "Anderson"} //rely on order.
alex := person{firstName: "Alex", lastName: "Anderson"}
alex.firstName = "Alex"

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pointers
&lt;/h3&gt;

&lt;p&gt;Go passes by value. It creates a copy when you pass a value. &lt;br&gt;
&lt;code&gt;&amp;amp;&lt;/code&gt; give the address of a value&lt;br&gt;
&lt;code&gt;*&lt;/code&gt; give the value of an address or define a pointer.&lt;/p&gt;

&lt;p&gt;Turn &lt;code&gt;address&lt;/code&gt; into &lt;code&gt;value&lt;/code&gt; with &lt;code&gt;*address&lt;/code&gt;.&lt;br&gt;
Turn &lt;code&gt;value&lt;/code&gt; into &lt;code&gt;address&lt;/code&gt; with &lt;code&gt;&amp;amp;value&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Value Types&lt;/th&gt;
&lt;th&gt;Reference Types&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;int&lt;/td&gt;
&lt;td&gt;slices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;maps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;channels&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;structs&lt;/td&gt;
&lt;td&gt;functions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;when passing a &lt;code&gt;reference type&lt;/code&gt;, go still make a copy, but &lt;code&gt;reference type&lt;/code&gt; is a reference. So, it is like passing by reference.&lt;/p&gt;

</description>
      <category>go</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Learning Golang 104</title>
      <dc:creator>jguo</dc:creator>
      <pubDate>Sat, 09 May 2020 22:36:40 +0000</pubDate>
      <link>https://dev.to/jiayanguo/learning-golang-104-2ida</link>
      <guid>https://dev.to/jiayanguo/learning-golang-104-2ida</guid>
      <description>&lt;h2&gt;
  
  
  Data
&lt;/h2&gt;

&lt;p&gt;Go has two allocation primitives, the built-in functions new and make. &lt;/p&gt;

&lt;h3&gt;
  
  
  Allocation with &lt;code&gt;new&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;it allocates memory, but it does not initialize the memory, it only zeros it (default value. check the definition &lt;a href="https://tour.golang.org/basics/12"&gt;here&lt;/a&gt;). It returns a &lt;strong&gt;pointer&lt;/strong&gt; to a newly allocated zero value of type.&lt;br&gt;
For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type SyncedBuffer struct {
    lock    sync.Mutex
    buffer  bytes.Buffer
}

p := new(SyncedBuffer)  // type *SyncedBuffer
var v SyncedBuffer      // type  SyncedBuffer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Constructors and composite literals&lt;br&gt;
Sometimes the zero value isn't good enough and an initializing constructor is necessary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func NewFile(fd int, name string) *File {
    if fd &amp;lt; 0 {
        return nil
    }
     return &amp;amp;File{fd: fd, name: name}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a composite literal contains no fields at all, it creates a zero value for the type. The expressions &lt;code&gt;new(File)&lt;/code&gt; and &lt;code&gt;&amp;amp;File{}&lt;/code&gt; are equivalent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Allocation with &lt;code&gt;make&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Make applies only to maps, slices and channels and does not return a pointer&lt;/strong&gt;. The reason is that these three types must be initialized before use. It returns an initialized (not zeroed) value of type T (not *T).&lt;/p&gt;

&lt;h3&gt;
  
  
  Arrays
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Keynote&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arrays are &lt;strong&gt;values&lt;/strong&gt;. Assigning one array to another &lt;strong&gt;copies&lt;/strong&gt; all the elements.&lt;/li&gt;
&lt;li&gt;In particular, if you pass an array to a function, it will receive a copy of the array, not a pointer to it.&lt;/li&gt;
&lt;li&gt;The size of an array is part of its type. The types [10]int and [20]int are distinct.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Do pass value, instead using point. value is expensive.
func Sum(a *[3]float64) (sum float64) {
    for _, v := range *a {
        sum += v
    }
    return
}

array := [...]float64{7.0, 8.5, 9.1}
x := Sum(&amp;amp;array)  // Note the explicit address-of operator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Slice
&lt;/h3&gt;

&lt;p&gt;Slices wrap arrays to give a more general, powerful, and convenient interface to sequences of data. Slices hold references to an underlying array, and if you assign one slice to another, both refer to the same array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (f *File) Read(buf []byte) (n int, err error)

n, err := f.Read(buf[0:32]) // read first 32 bytes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Maps
&lt;/h3&gt;

&lt;p&gt;Key-Value pair&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var timeZone = map[string]int{
    "UTC":  0*60*60,
    "EST": -5*60*60,
    "CST": -6*60*60,
    "MST": -7*60*60,
    "PST": -8*60*60,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;timeZone[key]&lt;/code&gt; returns two values. First one is the &lt;code&gt;value&lt;/code&gt;, second one is bool, &lt;code&gt;false&lt;/code&gt; if not present. &lt;code&gt;true&lt;/code&gt; if present.&lt;/p&gt;

</description>
      <category>go</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Learning Golang 103</title>
      <dc:creator>jguo</dc:creator>
      <pubDate>Sat, 09 May 2020 17:49:12 +0000</pubDate>
      <link>https://dev.to/jiayanguo/learning-golang-102-2fhk</link>
      <guid>https://dev.to/jiayanguo/learning-golang-102-2fhk</guid>
      <description>&lt;h2&gt;
  
  
  Functions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Multiple return values
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func nextInt(b []byte, i int) (int, int) {
    for ; i &amp;lt; len(b) &amp;amp;&amp;amp; !isDigit(b[i]); i++ {
    }
    x := 0
    for ; i &amp;lt; len(b) &amp;amp;&amp;amp; isDigit(b[i]); i++ {
        x = x*10 + int(b[i]) - '0'
    }
    return x, i
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Named result parameters
The return or result "parameters" of a Go function can be given names and used as regular variables.When named, they are initialized to the zero values for their types when the function begins; if the function executes a return statement with no arguments, the current values of the result parameters are used as the returned values.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func ReadFull(r Reader, buf []byte) (n int, err error) {
    for len(buf) &amp;gt; 0 &amp;amp;&amp;amp; err == nil {
        var nr int
        nr, err = r.Read(buf)
        n += nr
        buf = buf[nr:]
    }
    return   // default named result parameters.
}

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Defer
Go's defer statement schedules a function call (the deferred function) to be run immediately before the function executing the defer returns.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Contents returns the file's contents as a string.
func Contents(filename string) (string, error) {
    f, err := os.Open(filename)
    if err != nil {
        return "", err
    }
    defer f.Close()  // f.Close will run when we're finished.

    var result []byte
    buf := make([]byte, 100)
    for {
        n, err := f.Read(buf[0:])
        result = append(result, buf[0:n]...) 
        if err != nil {
            if err == io.EOF {
                break
            }
            return "", err  // f will be closed if we return here.
        }
    }
    return string(result), nil // f will be closed if we return here.
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>go</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
