---
# System prepended metadata

title: integration team questionnaire 2022 June

---

# integration team questionnaire 2022 June
## overview
 This exam contains following sections

* coding practice
* golang insight
* communicating technical issue
## coding practice
* extract and transform data is one of the foundation feature of API gateway.
* the coding practice is to write simple transformation to show your coding/design skills using golang

### sample json
```
{
  "version": "1.0",
  "rules": [
    {
      "resource": {
        "path": "/api/data/documents"
      },
      "allowOrigins"["http://this.example.com","http://that.example.com"],
      "allowMethods": [ "GET" ],
      "allowCredentials": true
    }
  ]
}
```
### expected result
* read json file with camel case key field and write out coverted key field name as snake_case
* using stand library only. don’t use any 3rd party library/framework
* allowed language: golang
:::success
 ```
 type Rule struct {
	Resource struct {
		Path string `json:"path"`
	} `json:"resource"`
	AllowOrigins     []string `json:"allowOrigins"`
	AllowMethods     []string `json:"allowMethods"`
	AllowCredentials bool     `json:"allowCredentials"`
}

type InputStruct struct {
	Version string `json:"version"`
	Rules   []Rule `json:"rules"`
}

type NewRule struct {
	Resource struct {
		Path string `json:"path"`
	} `json:"resource"`
	AllowOrigins     []string `json:"allow_origins"`
	AllowMethods     []string `json:"allow_methods"`
	AllowCredentials bool     `json:"allow_credentials"`
}
 ```
 
 ```
 func main() {
    //為了打印結果，在生產環境可直接將interface resposne給前端
	log.Println(string(ResultStructTagsModify().([]byte)))
  }
 
 func ResultStructTagsModify() interface{} {
	input := `{
               "version": "1.0",
               "rules": [
                         {
                          "resource": {"path": "/api/data/documents"},
                          "allowOrigins": [ "http://this.example.com", "http://that.example.com"],
                          "allowMethods": [ "GET" ],
                          "allowCredentials": true
                         }
                        ]
              }`

	var inputData InputStruct
	if err := json.Unmarshal([]byte(input), &inputData); err != nil {
		log.Panic(err)
	}
	newRules := make([]NewRule, 0)
	for _, rule := range inputData.Rules {
		var newRule NewRule
		newRule.Resource = rule.Resource
		newRule.AllowOrigins = rule.AllowOrigins
		newRule.AllowMethods = rule.AllowMethods
		newRule.AllowCredentials = rule.AllowCredentials
		newRules = append(newRules, newRule)
	}
	newStruct := struct {
		Version string    `json:"version"`
		Rules   []NewRule `json:"rules"`
	}{
		Version: inputData.Version,
		Rules:   newRules,
	}
	result, err := json.Marshal(newStruct)
	if err != nil {
		log.Panic(err)
	}
	return result
}
 ```
:::

### food for thought
* what will you do to handle generic/arbitrary json format?

:::success
 <font color="black">使用interface{} type 或者以 reflect.typeOf() 來判斷型別</font>
:::
 
## golang insight
### OOP

```
// You can edit this code!
// Click here and start typing.
package main

import "fmt"

type data struct {
	num   int
	key   *string
	items map[string]bool
}

func (this data) updateData(value int) {
	this.num = value
	*this.key = "updated"
	this.items["updateData"] = true
}

func main() {
	key := "first"
	d := data{1, &key, make(map[string]bool)}
	fmt.Printf("num=%v key=%v items=%v\n", d.num, *d.key, d.items)

	d.updateData(8)
	fmt.Printf("num=%v key=%v items=%v\n", d.num, *d.key, d.items)
}
```
* what would be the output?
:::success
  ```
  num=1 key=first items=map[]
  num=8 key=updated items=map[updateData:true]
  ```
:::

* what would you modify to make better result? why?
:::success
```
type data struct {
	Num   int             
	Key   *string        
	Items map[string]bool 
}

type IData interface {
	InitData()
	UpdateData()
}

func (r *data) InitData() {
	fmt.Printf("num=%v key=%v items=%v\n", r.Num, &r.Key, r.Items)
}

func (r *data) UpdateData() {
	fmt.Printf("num=%v key=%v items=%v\n", r.Num, &r.Key, r.Items)
}

func main() {
	var d IData
	// initial
	key := `first`
	d = &data{1, &key, map[string]bool{}}
	d.InitData()
	// update
	key = "updated"
	d = &data{
		Num:   8,
		Key:   &key,
		Items: map[string]bool{"updated": true},
	}
	d.UpdateData()
}
```
<font color="black">
將initial, update 改寫成物件形式，可以提升可讀性、及方便管理functions。
</font>
:::

### loop variable
```
func main() {

    samples := []string{"cloud", "d2nova", "evox"}
    for _, name := range samples {
        go func() {
            fmt.Println(name)
        }()
    }

    // wait before exiting
    time.Sleep(3 * time.Second)
}
```

* what would the possible output of this code snippet
:::success
<font color="black">
evox<br>evox<br>evox
</font>
:::
* what is the root cause/explanation the result? is that a bug or feature of golang?
:::success
<font color="black">
Race Condition<br>
執行過程中創建的goroutine同時對name做存取   
</font>
:::
* what would you do to change the code for better result? why?
:::success

```
func main() {
	var wg sync.WaitGroup
	samples := []string{"cloud", "d2nova", "evox"}
	for _, name := range samples {
		wg.Add(1)
		go func(n string) {
			fmt.Println(n)
			wg.Done()
		}(name)
	}
	wg.Wait()
}
```
<font color='black'>
改以依序傳入name value，就可以避免race condition，
同時將time.sleep()改用waitGroup，資料量大時waitGroup能保證線程安全；
資料量小時，資料處理完成也不需等待time.sleep()結束。
</font>

---

 
```
 結果：     
 cloud
 evox
 d2nova
```



:::
## written/oral communication
### oauth2
* what is oauth2? write down your understanding.
:::success
<font color="black">
  可設有oauth server 獨立於主要的業務邏輯API之外，
  對oauth server 發出請求可以得到包含access token, expired, scope 等資訊。<br>
  接著clients 將access token攜帶於reqest中向主要的業務邏輯API發出請求。<br><br>
    
  我的實際經驗也有使用過Google Oauth，係向google 驗證登入之email address是否為合法的，frontend可以取得一個token,將之傳遞給backend，由backend使用該token向google驗證並取回登入資訊。由backend使用該token向google驗證並取回登入資訊。
</font>
:::
* if need to explain to 3rd party developer to allow them to access your api, what will you do?
:::success
 <font color="black">
可使用Swagger API格式或者使用類似hackmd或者Gitbook有支援markdown格式的編輯器撰寫API spec.
下例是曾經寫過的使用markdown撰寫的API spec
</font>
:::
### Register
:::info
POST v1/User/Register
>>
>>
|Body|Type|Description|Format|
|:--:|:--:|:---------:|:----:|
|Email*|String|信箱|x-www-form-urlencoded,JSON|
|Pwd*|String|密碼|x-www-form-urlencoded,JSON|
|Name*|String|真實姓名|x-www-form-urlencoded,JSON|
|NickName*|String|暱稱|x-www-form-urlencoded,JSON|
|Birthday|String|生日|x-www-form-urlencoded,JSON|
:::

