2021年3月13日 星期六

2020 年底 Junior Frontend engineer 面試記錄暨求職心得

轉職動機:

    在 104 投了大約 30 家履歷,cakeresume 4 家,得到面試機會 5 次。筆者背景是 2019 年底

開始積極準備轉職,原本是象棋教師,觸動我轉行的動機是每個行業的薪資上下限就在那,

結構性問題也不是個人可以改變的,於是選擇六角學院作為主要的學習管道開始學習前端,

理由是對於學習路線描述的很清楚:連結,前端一方面比後端好上手,一方面是作出來的成果

直接在畫面上回饋感強,再來搜尋各家工程師從業心得,大概都是需要不斷學習,剛好我就是

喜歡學習研究的人,於是就入了這個坑。


學習時間及過程:

    配合活動的六角工商,介紹一下六角的學習歷程:在六角有買 jQuery、JavaScript、Vue...

等等,但是後來出的切版直播班跟 Vue 作品直播班比較有衝刺的效果,學習時間的話,在直播

班寫作業的時候,全職的時候就趁半夜沒聲音的時候狂寫,平均八小時,兼職的時候就比較

規劃平均只有兩個小時。最後把作品直播班作品作出來之後,精實修改了 300 條左右程式跟

設計上的建議,配著加碼的履歷健檢跟模擬面試,還有自己趁機寫的一些 F2E、Chart.js 小作品

就開始求職了。

    時間大約從六角最後一次改作業然後模擬面試完,2020/10月底到2020/12月底拿到 offer letter

 為止。職缺都是前端,Vue 或 React 都投,薪資條件都開 4 萬。


面試紀錄:


科技公司A:

    在 cakeresume 上投履歷得到回應。


    作寶寶攝影機,連 APP,母嬰分房照顧之類的時候很方便,覺得我有小孩就會買的一個

產品,第一關電話面試,自我介紹、介紹作品,由於這家是最早面試的,所以履歷上只有六角

的主要作品,作了一些技術問答後,問公司對工程師的配置,前端只有一個人,大部分都是

 APP 或後端,公司直接表明不適合,給了一段發問閒聊時間。


    其中一個建議:作品介紹的時候可以從主題如何發想開始,在我後來的面試中也有很大的

幫助。


準備的對公司問題:

    主管已說明主要負責 Vue 的一些工具 component 跟網站前端。

    前端團隊的配置?1前端,其他都是 APP 或後端。


健身公司A:

    caseresume 投履歷得到回應。

考卷回應後無聲卡。題目主要是 LeetCode 。


博弈公司A:

    104 上公司主動邀約面試。


    遊戲開發部主管、前端主管、資深工程師三人面試,最後HR問常見的面試問題,12/1面試、

預計12月底回復,結果無聲卡。


面試內容:

    自我介紹、ES6 var let const 差異、箭頭函式、.map、怎麼把陣列中重複的東西去掉,有些

忘了。工程師有看過作品,詢問購物車作法,使用 API 或 localstroge 儲存資料的差異,有教我

一般是用 localstroge 儲存購物車資料,最後才 post API。

六角的學習經歷跟製作作品時間,git  commit 怎麼忽略檔案。


準備對公司的問題:

    公司做什麼的?博弈(從在內湖主動邀約大概可以猜測)。

    團隊組織的組成?公司使用的框架?組織:遊戲開發部,兩個各四人的前端 team、以 React 

框架為主。

    哪些地方可以進步?實做作品數量、團隊溝通經驗。


11月中到12月中,中間花了一個星期多邊投邊補了幾個自己作的東西,一方面作自我研究,104 的職缺比較多所以後來都主投 104 為主。

   

接案公司A:   

    104 上投履歷,第二天收到電話聯絡。

    面試過程首先人資,再來業務經理。

    事前有說看作品,所以先接網路把 github pages 弄出來,介紹作品,問轉職的原因,談到公司

有外派或自身開發需求前端,期望薪資開4萬,104上寫5萬~6萬,不過我沒刻意開高,然後找

經理來。再介紹一次作品,經理有想看後台、旅館預約服務、將新研究的 Chart 作小修改。

我後台有顏色跑掉的問題,因為沒在顧畫面,做完自製產品就沒再開跟檢查了,如果要投會做

後台的公司要注意一下,Chart 的圖表製作來源,因為沒 API ,就用 JSON Server 玩看看,結果

差點改到壞掉,好險只是因為 VSCode 開過別的資料夾,JSON Server 要重開。


    公司想作新產品從 0 開始,會用腦力激盪的方式開會討論,產品開發的週期會比一般接案

開發更長,會有加班時間,前期自我研究會比較多,有資深工程師但應該靠自己研究比較多,

表單處理會比較多,有提到缺開給 Junior 是為了研究熱情(加班需求)?

    預計 12 月中有回應,結果無聲卡。


現職公司:


    104 上公司主動邀約面試,一開始傻眼履歷上都是 Vue ,職缺寫 React 工程師,不過抱著當

練習順便試試自己的功力就去了。


  三階段:考試、人資、技術主管

筆試:30分鐘技術問題 10分鐘DISC。應該30分鐘就全寫完了,忘了問能不能 google 就先不用

手機。


考題:

1. for(var i = 0; i < 5; i++){
           settimeout(()=>{console.log(i),1000}
     )} 為什麼出現5次i都相同?怎麼解決?

    考同步觀念。


2. 傳址問題  a = {}  b= {}  c=a  a ===b  a===c true or false?

    考物件傳址。


3.從1-n 之間產生不重覆隨機數生成一個新陣列(邏輯)

    這題最不會,討論最久,應該要用我忘了的 while 迴圈。


4.很多層的元件應該如何傳值?

    剛好有研究平行組件傳值,就用 Vuex 答,對應 react 應該是 Redux ,父子元件傳值 Eventbus

會很多層而且 Vue3 也要改,算近期看得,研究過程跟作法都答得蠻詳細的,只有 Vuex 除了

傳值以外的狀態沒仔細看。


5.如何增加首次瀏覽網頁的載入速度?

Lazyload、檔案大小...之類的。


6. React array .map為什麼 key 最好不要用 index ,用 id 之類的?

    我用 v-for 的觀念答,後來看文件才知道 React 的 map 大概就跟 Vue 的 v-for 差不多。
剩下忘了

人資:問詳細經歷,介紹作品,我比較菜就鉅細靡遺的從首頁講到產品列表講到購物車,聽得

完真的蠻猛的,介紹制度福利。

技術主管:有兩位,從考題錯的或可以改進的透過腦力激盪的方式問答,大概有非同步的

作法,有數十隻 API 分散在不同 component 要如何管理,我之前剛好看過 Mike 的API 管理那篇

文章,詳細作法當然是忘了,因為實作都兩三隻直接套就好了,詳細補完在 blog ,後面幾題

比較偏向 React 框架應用我不知道,都用 Vue 的作法回答,作品改CSS,改呈現方式。

總過程大概兩個半小時,不過有磨練到,後來得到這家的 offer。至今兩個多月的歷險記又是

另一篇故事了...。

心得:

       原本打算拖稿到就職三個月再寫,不過配合六角活動就趁假日寫一寫,旁邊還有要抽空改

的公司專案,建議大概就是欠技術債就是要還,我認為在六角學習,最有價值的就是實戰班

作品作完以後修改的那兩個半月,跟在公司作東西被退回修改的情境有87%像,作業有設計

稿,有時候還會直接給你關鍵字研究,我最近都只拿到一張 line 貼圖就要開始改了,上實戰班

的時候,原本有些技術問題都先繞過,或上課聽不懂得就先放著,結果最後還是全學起來了,

到工作的時候,最有挑戰的不是功能作不作得出來,而是要用符合團隊的作法或技術去達成。


最近活動用連結: 六角學院









2021年1月24日 星期日

應用 TypeScript Eunm 完成分類,跟就職一個月心得

    很久沒發文了感覺很廢,所以舉一個最近工作學到的東西,公司採用的框架是 React、Nest、

Typescript、Styled,所以階段性任務都在學怎麼切 React Component,跟尋寶(找有沒有前人建好

的 Component可以套或事先包好的常數),還有整個開發流程,組織算蠻扁平的,發現測試環境

掛了可以直接去問後端,同事也蠻友善。


任務大概是做一顆有三種狀態的按鈕,onClick 一個方法大家都會,Vue 跟 React 有個不同的

地方是渲染方式,Vue 只要在 data 先 set 好,數據雙向綁定跟畫面渲染通常沒太大問題,

但 React 數據是向下傳遞,一開始我還想要作兩個組件然後平行組件傳,在 React 依然是件困難

的事,並且公司的東西也不能因為一個小組件就讓你隨便傳值到 store 借放,後來作成一個組件

將按鈕控制的畫面跟按鈕放在一起,大不了把按鈕用絕對定位定到天涯海角,因此還要將畫面

的狀態設置成一個 hook ,React 才會監控並在數據變更的時候重新渲染,一開始我會 if 連發:


let status = 0

if( status === 0 ){

    狀態0

    status = 1   //切換到下一個狀態

} else if (status === 1){

    狀態1

    status = 2   //切換到下一個狀態

} else {

    狀態2

    status = 0

}


後來運用 switch:


switch(status){

case '0':

    狀態0,

    break

case '1':

    狀態1,

    break

case '2':

    狀態2,

    break

}


至此剩下一個問題是,case 0、1、2 過幾個月別人會看不懂,雖然本人通常會記得是怎麼

回事,所以這時候就要用 Eunm 把 case 變成英文:


eunm name {

OPEN:'OPEN'

'0.5X':'0.5X'

CLOSE:'CLOSE'

}


const [mode, setMode] = useState('OPEN')


React 的 useState,可以用 setMode 改變 mode 的值並重新渲染影響範圍。


change( ) => {

const nameArray = [name[OPEN], name[0.5X], name[CLOSE]]

const modeLength = nameArray.indexOf(mode)

( modeLength + 1 ) > nameArray.length ?

 setMode( nameArray[0] ) : 

 setMode(nameArray[modeLength + 1])

}

首先先做一個 enum 內容的陣列,然後找出現在狀態是第幾種,之後作一個沒事 length + 1 跳到

下一個狀態,到底則回到第一種( length = 0 )狀態的判斷。

雖然實際上的程式會變比較多行比較繞,但是在這裡可讀性的要求在節省行數之前。




參考資料:

神Q超人介紹的 Eunm

2020年12月25日 星期五

React api 管理及應用 axios

    最近剛拿到 React 的 offer ,惡補一下,看六角的洧杰老師的文章提到最好是七成舊,三成新才比較容易聚焦問題避免整組壞光光不知道從何改起,或是進步太少,之前用 Vue Promise 處理 API 駕輕就熟,直到看到 Mike 的文章跟面試真的有人問有幾十隻 API 分散在不同 component 要怎麼處理,才拿這篇出來救駕,今天來實作如何用建立一個 JS 檔案的方式管理 API。

首先先建立拿來管理 API 的檔案 api.js

然後 import axios

import axios from 'axios';

建立不同大分類以及 baseUrl

const sixUrl = axios.create({
  baseURL: 'https://course-ec-api.hexschool.io/'
})

每個大分類下的不同分支 API

export const productList = () => sixUrl.get(`api/${uuid}/ec/products`)

uuid 是 get 六角 API 用的就不貼了,可依照各 API 權限控管進行調整。

回到需要使用的頁面,import api.js,並且選擇有 export 的 API

import { productList } from "./api";

透過 async await 完成 getData

function Home() {
  async function getData () {
    try {
      const item = await productList()
      console.log(item)
    } catch (err) {
      console.log(err)
    }
  }
  console.log(getData())
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}

console.log(item) 有資料就成功啦,基礎用法就到這邊,接下來要研究如何與 hook 一起使用作畫面更新。


參考資料:

Mike 的文章

2020年12月11日 星期五

Vue 使用 vue-drag-drop 完成 Drag & Drop

 Drag & Drop 就是網站的拖曳效果,今天要達成的目標就是有兩個區域A及B,裡面有資料,

把資料拖曳到任一個區域都可以在該區域新增資料,並刪除原區域內的資料。透過 HTML 的

拖放 API,設定多而且 DOM 的長度可觀。


原理簡略的說: Drag 是可拖動的物件,Drop 是可放置的區域,透過今天使用的套件,可以使 

Drag 帶著資料去觸發 Drop 的事件,達成放置資料或其他操作。


import VueDragDrop from 'vue-drag-drop';
Vue.use(VueDragDrop);

先 import 跟 use,官方文件有一個範例,比較接近 Basic list support ,不過這個範例有幾個需要

改變的地方,第一個是兩個區域不能總貼在一起,再來是如何讓排列順序是有序的,範例中

使用 .sort 進行陣列重排,我希望跟積木一樣可以使用者將資料移到那就把資料放在那。


<template>
<div>
  <div class="container">
    <div class="row">
      <div class="col-3">
        <div class="drop">
          <div v-for="(item, i) in testList[0]" :key="i">
            <drop @drop="drop1(item, ...arguments)">
              <drag class="drag"
                :transfer-data="{ item: item, list: testList[0], example: 'lists' }">
                {{ item }}
              </drag>
            </drop>
          </div>
        </div>
      </div>
      <div class="col-9">
        <div class="drop">
          <div v-for="(item, i) in testList[1]" :key="i">
            <drop @drop="drop2(item, ...arguments)">
              <drag class="drag"
                :transfer-data="{ item: item, list: testList[1], example: 'lists' }">
                {{ item }}
              </drag>
            </drop>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
</template>


template 使用 bootstrap 進行簡單的排版,左右有兩個框,分別放置 testList[0] 跟 testList[1] 的

陣列,裡面的資料稍微用 CSS 讓資料變清楚,不同的區域基本方法是相同只是觸發區域

不一樣,可以看到每個 item 有一個 drop 讓 drag 可被放上去,也有 drag 讓 item 可被拖曳,

<drag> 以及<drop> 標籤就是 vue-drag-drop 套件替你省下了無數的 DOM 指令。


@drop(item, ...arguments) 方法是官方推薦的,表示當 drag 被放進 drop 時觸發的方法,第一個參數是 drop 所在的元素,第二個參數是 drag 額外帶的 data。 drag攜帶資料的方法:

<drag class="drag"
                :transfer-data="{ item: item, list: testList[1], example: 'lists' }">

利用 :transfer-data,攜帶 drag 的 item ,所在的 array ,或其他。


最後處理方法,只要清楚 drag 在哪? drop 在哪? 那哪裡應該放置新資料或刪除已移動的資料就是小事了。splice(索引, 從索引之後刪除幾項, 加入的資料)。


methods: {
    drop1 (item, data) {
      const testlist = data.list
      // drag 所在的陣列
      this.testList[0].splice(this.testList[0].indexOf(item), 0, data.item)
      // 接收的 drop 新增 item
      testlist.splice(testlist.indexOf(data.item), 1)
      // 刪除原陣列的 item
    },
    drop2 (item, data) {
      const testlist = data.list
      // drag 所在的陣列
      this.testList[1].splice(this.testList[1].indexOf(item), 0, data.item)
      // 接收的 drop 新增 item
      testlist.splice(testlist.indexOf(data.item), 1)
      // 刪除原陣列的 item
    }
  }


成品圖:兩個區域為了清晰加了一個固定大小的框,所以如果全部資料都在同一個區域會爆版,自行調整 CSS 即可。




參考資料:

MDN

vue-drag-drop 文件

2020年12月7日 星期一

vue-chart.js 及 Chart.js 在 Vue 中製作圖表

 Chart.js 是個可以方便製作圖表的 JavaScript library,可以在 HTML 中產生一個 canvas 物件產生

圖表。這篇以線圖舉例。


首先先 npm 安裝

npm install vue-chartjs chart.js --save


 Chart.js 的基本寫法是 new Chart,綁定一個 ID,裡面有三個參數:圖表類型( examle: line )、

資料內容 ( data )、選項( option ),HTML 中的 canvas 物件可以直接設定大小,但今天用 Vue,

所以要看看有什麼不同。


首先用 Vue 渲染的 canvas 是不能有 template 的,意味著通常要用 components 方式載入,不然整個畫面只有圖,使用 .vue 或 .js 檔案皆可,筆者比較習慣用 .vue。先製作空白圖表的 components。

在components 資料夾下新增 Chart.vue


import { 圖表種類 } in 'vue-chartjs';
extends: 圖表種類,
使用 mounted 得到資料後繪圖,圖表種類已經 import 過了,所以剩下 data、option 兩個參數。
一張圖表可以輸入不同的資料匯出不同的線圖,所以用 props 讓空白的表接收父組件的數據。

接下來回到父組件:

import 子組件 + components 子組件

import Chart from '../components/Chart.vue';
components: {
    Chart,
  },

template 放入組件的部分:

<template>
  <div>
    <div class="container">
      <div class="row">
        <div class="col-6">
          <chart v-if="loaded"
            :chartdata="chartdata"
            :options="options">
          </chart>
        </div>
      </div>
    </div>
  </div>
</template>


筆者有用 bootstrap 框架,這樣可以控制子組件,也就是圖表的大小,將 data 與 option 傳入組件,
為什麼要加上 v-if ?因為組件得到數據之後,"不會"重新繪圖
所以要透過確認有得到數據才繪圖。


json 格式的 data,沒有 API ,用 json-server 模擬從 API 得到資料,npm install -g json-server,用 VSCode ctrl+`打開終端機,然後 json-server --watch 想要觀測的檔案,沒取名照教學是db.json,npm install --save axios vue-axios 用來串接 API,別忘了 main.js 要加入 Vue.use(VueAxios, axios) 。


資料格式:

 data() {
    return {
      chartdata: {
        labels: [],
        datasets: [
          {
            label: '0050',
            fill: false,
            backgroundColor: 'rgba(188,96,147,1)',
            borderColor: 'rgba(212,85,49,1)',
            pointBackgroundColor: 'rgba(41,56,69,1)',
            data: [],
          },
        ],
      },
      options: {
        title: {
          display: true,
          fontSize: 24,
          text: '2020/11 0050 價格走勢',
        },
      },
      loaded: false,
    };
  },


chartdata 與 option 都必須是物件,chartdata 裡面就是 data,有兩個屬性,第一個 lebal 是 x 軸的值,是陣列,而 y 軸的值放在 datasets 的 data 下面。

將 json server 的數據陣列加入,並在 create 階段載入:

created() {
    this.getData();
  },
  methods: {
    getData() {
      const api = 'http://localhost:3000/0050';
      this.$http.get(api).then((res) => {
        this.chartdata.labels = res.data[0].Date;
        this.chartdata.datasets[0].data = res.data[0].Price;
        this.loaded = true;
        this.$forceUpdate();
      }).catch((error) => {
        if (error) {
          console.log(error);
        }
      });
    },
  },


中間有混入一個 loaded ,就是剛剛提到的拿來判斷是否收到數據,啟動子組件的繪圖。

最後就是剩下看文件找適合的選項把標題跟圖表畫的美美的。


附上 json 的結構,這個表是從證交所下載 .csv 並手動重製,x 軸為時間,y 軸為當天價格:



 


參考資料:

https://www.chartjs.org/

https://vue-chartjs.org/

https://dylan237.github.io/json-server.html

2020年12月4日 星期五

npm報錯:code ENOENT

 Google了一下發現是 npm 不知為何找不到正確的路徑,解決方法是

將 node_modules 資料夾刪除,再重新 npm install,之後就恢復正常了。


嘗試過 npm cache clear、npm install 有安裝過的套件、更新 Node.js 及 Vue Cli。


參考資料:

https://blog.csdn.net/weixin_43170297/article/details/96436565

https://stackoverflow.com/questions/17990647/npm-install-errors-with-error-enoent-chmod/23446110

https://juejin.cn/post/6864809486675574792

2020年12月2日 星期三

初學 TypeScript,型別註記的方法

 TypeScript 是強型別語言,相對於 JavaScript 的弱型別,例如 1 可以是 number ,也可以是 '1' 字串,如果是外部資料甚至是自己筆誤會得出錯誤結果而不自知。


TypeScript 簡單的定義型別的方法是用 : ,例如:

let name: string = 'Jack';


物件的定義:

let account: {name: string, password: string} = {

  name: 'Jack',

  password: 'abc4567',

};


函式的定義:


let addition = function(param1:number, param2:number) {

  return param1 + param2;

};


使用 type 作出一組型別定義,使用方法跟上述一樣接在:後面:

type accountInfo = {

  account: string,

  password: string,

  nickname: string,

  birth: Date,

  subscribed: boolean,

};


在 TypeScript 覆寫物件屬性值會有一個問題是必須完全覆寫,但以帳號資料或購物資料表單為例,實務上常常會有許多選填,因此需要選用註記?。


type accountInfo = {

  account: string,

  password: string,

  nickname?: string,

  birth?: Date,

  subscribed?: boolean,

};


let accountData: accountInfo = {

  account: 'Jack',

  password: 'abc1234',

}

雖然缺少了 nickname...等三個屬性沒有完全覆寫,但可以通過 TypeScript 的檢驗,筆記資料較為精簡,原文有詳細及深入的範例探討,有鐵人賽文章及實體書可選看。

參考資料:讓 TypeScript 成為你全端開發的 ACE! Day1~Day9