---
title: 2021 年資訊科技產業專案設計課程面試範例
tags: INFO2021
---
# 2021 年「[資訊科技產業專案設計](https://hackmd.io/@sysprog/info2021)」面試範例
> 貢獻者: 琪怪 ChiGuai
> ==[video](https://youtu.be/_eIbSRmkFKo)==
---
# info2021-homework1
## Leetcode 66. Plus One (等級:Easy)
### 題目
```
You are given a large integer represented as an
integer array digits, where each digits[i] is the ith
digit of the integer. The digits are ordered from
most significant to least significant in left-to-
right order. The large integer does not contain any
leading 0's.
Increment the large integer by one and return the
resulting array of digits.
```
### 討論
- 從最小位數依序往高位數看
- 若該位數不是9,則該位數加1後return
- 若該位數是9,則將該位數值設為0,再繼續探討下一個位數
- 若最高位數是9,則在vector的最前面插入1之後再return
> 改進方案: 能否使用遞迴形式實作?
### 程式碼
```cpp=
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
for (int i = digits.size() - 1; i >= 0; i--)
{
if(0 <= digits[i] && digits[i] < 9)
{
digits[i] = digits[i] + 1;
return digits;
}
else
{
digits[i] = 0;
if(i == 0)
{
digits.insert(digits.begin(), 1);
return digits;
}
}
}
return {-1};
}
};
```
### 程式碼(遞迴版本)
```cpp=
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
add_index(digits, digits.size() - 1);
return digits;
}
void add_index(vector<int>& digits, int index)
{
if (digits[index] != 9) {
digits[index]++;
return;
} else {
digits [index] = 0;
if (index == 0) {
digits.insert(digits.begin(), 1);
return;
}
add_index(digits, index - 1);
}
}
};
```
## Leetcode 58. Length of Last Word(等級: Easy)
### 題目
```
Given a string s consisting of some words separated
by some number of spaces, return the length of the
last word in the string.
A word is a maximal substring consisting of non-space
characters only.
```
### 討論
- 從最開始依序往後找
- 主要探討前面一個index跟本身的index關係,藉此知道是開始新word、在word之間、結束一個word或是在空格堆中
- 若前一個index及現在的index非空,表示在word之間,則計數加1
- 若前一個index為空,現在的index非空,表示開始一個新字節,計數歸回1
- 若前一個index非空,現在的index為空,不做事(已於一開始設初始值為1)
- 若前一個index為空,現在的index為空,不做事
- 至於計數從1開始,是避免一開始的第一個index無法跟前一個index去做比較
> 改進方案:為何不從後面開始找?
- 探討前面一個跟本身是不是空格,決定Word是否需要重新計數
- 從最後面開始往前
- 若前一個index為空,現在的index非空,表示開始下一個新字節,可以break迴圈
### 程式碼
```cpp=
class Solution {
public:
int lengthOfLastWord(string s) {
int temp = 1;
int i;
for (i = 1; i < s.length(); i++) {
if(s[i] != ' ' && s[i-1] == ' '){
temp = 1;
}
else if(s[i] != ' ' && s[i-1] != ' '){
temp ++;
}
else if(s[i] == ' ' && s[i-1] != ' ') {
continue;
}
else if(s[i] == ' ' && s[i-1] == ' ') {
continue;
}
}
return temp;
}
};
```
### 程式碼(從後面開始往前找)
```cpp=
class Solution {
public:
int lengthOfLastWord(string s) {
int temp = 1;
int i;
for (i = s.length() - 1; i > 0; i--) {
if(s[i] != ' ' && s[i-1] == ' '){
break;
}
else if(s[i] != ' ' && s[i-1] != ' ') {
temp ++;
}
else if(s[i] == ' ' && s[i-1] == ' ') {
continue;
}
else if (s[i] == ' ' && s[i-1] != ' ') {
continue;
}
}
return temp;
}
};
```
## Leetcode 151. Reverse Words in a String (等級: Medium)
### 題目
```
Given an input string s, reverse the order of the words.
A word is defined as a sequence of non-space characters. The
words in s will be separated by at least one space.
Return a string of the words in reverse order concatenated by a single space.
Note that s may contain leading or trailing spaces or
multiple spaces between two words. The returned string
should only have a single space separating the words. Do not
include any extra spaces.
```
### 討論
- 從最後面的index依序往前看
- 並且與前一個index比較判斷目前word的狀態
- 一個word結束,使用string的append功能將前一個word加到final_words之中
- 開始新的word,先將last的index設為目前的index,如果不是第一個word的話,先加進空白鍵
- 使用start跟last分別記下word開始與結束的index
> 改進方案:試著用看看stringstream呢?
### 程式碼
```cpp=
class Solution {
public:
string reverseWords(string s) {
string final_words;
int last = s.length(); int start;
int i;
for (i = s.length() - 1; i >= 0; i--) {
if (s[i] == ' ' && s[i+1] != ' ') {
start = i + 1;
final_words = final_words.append(s, start, last - start + 1);
}
else if (s[i] != ' ' && s[i+1] == ' ') {
last = i;
if (final_words.length() != 0){
final_words = final_words + ' ';
}
}
if (i == 0 && s[i] != ' ') {
start = i;
final_words = final_words.append(s, start, last - start + 1);
}
}
return final_words;
}
};
```
### 程式碼(使用stringstream)
```cpp=
class Solution {
public:
string reverseWords(string s) {
stringstream str(s);
string temp;
vector<string> vec;
while(str>>temp)
{
vec.push_back(temp);
}
reverse(vec.begin(),vec.end());
string ans = ‘’;
for(int i=0;i<vec.size()-1;i++)
{
ans = ans + vec.at(i);
ans = ans + ‘ ‘;
}
ans = ans + vec.at(vec.size()-1);
return ans;
}
};
```
## 初步檢討自己的表現
1. 語速偏慢,打字速度偏慢,對於鍵盤快捷鍵不熟
2. 講話講到一半會停頓下來打程式
3. 語句間很多冗詞贅字,例如:`那`、`然後`
4. 蠻常打錯字
5. 程式碼太長,無法完整顯示在螢幕上
# info2021-homework2
## Leetcode 66. Plus One (等級:Easy)
### 題目
```
You are given a large integer represented as an
integer array digits, where each digits[i] is the ith
digit of the integer. The digits are ordered from
most significant to least significant in left-to-
right order. The large integer does not contain any
leading 0's.
Increment the large integer by one and return the
resulting array of digits.
```
### 對話討論記錄
角色介紹 :boy: interviewer怪奇 :fish: interviewee 琪怪
:boy: 嗨,琪怪。我是interviewer怪奇。想請問你了解lvalue跟rvalue的定義嗎?
:fish: 左值與右值通常出現在運算式中。左值常指的是運算式後還保留其狀態的一個物件,像是大部分的變數都是左值。而右值常指的是一個運算式過後其狀態就不會被保留了,就是一個暫時存在的數值。就像是int a = 4 + 3; a就是左值,4+3就是右值。
:boy: 請問`++x`與`x++`分別是左值還是右值呢?
:fish: `++x`因為是先+1再賦值給x,所以是左值。而`x++`是先賦值給x,再+1,所以是右值。
:boy: 想請你實作一個function,它是一個vector,裡面將正整數的每個位數分開存放,從高位數開始依序存放到最低位數。要作的事情就是將這個數字加1並回傳。
:fish: 請問意思是如果有一個正整數123,存放在vector為[1,2,3]而我需要將123+1變124,再回傳[1,2,4]嗎?
:boy: 沒錯!不知道你對這題有什麼想法?
:fish: 可以從最低位數往高位數探討,若是該位數不是9,就將該位數加1並回傳。若是該位數是9,則將該位數設成0並往更高位數探討之。若是到最高位數都還是9,則除了將該位數設成0外,在vector的最前插入數字1。
:boy: 請你邊實作邊講解一下你的程式碼。
:fish: <開始邊打程式碼邊講解>
:boy: 請問你知道vector.insert是怎麼實作的嗎?
:fish: vector底層都是通過迭代器進行操作的,也就是指標。一開始會先檢查插入位置的有效性,由於增加容量會導致pos迭代器失效,所以我們可以先保存pos相對於起始位置的偏移量,增加容量後再將pos重新賦值。插入後,再更新vector的末位置值。
:boy: 時間差不多了,今天的面試就到這邊,謝謝。
### 程式碼
```cpp=
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
for(int i = digits.size()-1;i>=0;i--)
{
if(digits[i]!=9)
{
digits[i]++;
return digits;
}
else
{
digits[i] = 0;
if(i==0)
{
digits.insert(digits.begin(),1);
return digits;
}
}
}
return {-1};
}
};
```
## Leetcode 58. Length of Last Word(等級: Easy)
### 題目
```
Given a string s consisting of some words separated
by some number of spaces, return the length of the
last word in the string.
A word is a maximal substring consisting of non-space
characters only.
```
### 對話討論記錄
角色介紹 :boy: interviewer怪奇 :fish: interviewee 琪怪
:boy: 嗨,琪怪。歡迎來到下場面試。想請問你知道char array跟string之間的差別嗎?
:fish: 在C語言中並沒有string,但是可以用char array來表示string, 但要特別注意char array使用`{}`給值時要在最後面加`\0`,使用""時則可以不用。
:boy: 如果用`{}`賦值但沒有加上`\0`會發生甚麼事呢?
:fish: 因為char array會不知道字串結束,所以可能會出現亂碼。
:boy: 想請你實作一個函數,他會輸入一組字串,每個字之間可能有很多空格,請你回傳最後一個字的英文字母個數。如"the sky is blue",這時候因為blue有4個英文字母就要回傳4。
:fish: 請問如果blue後面有很多空格也是一樣回傳4嗎?
:boy: 沒錯!後面的空格省略不作計算。
:fish: 我認為可以從最後面依序往前找,主要探討前面一個index跟本身的index關係,藉此知道是開始新word、在word之間、結束一個word或是在空格堆中
- 若前一個index及現在的index非空,表示在word之間,則計數加1
- 若前一個index為空,現在的index非空,表示word結束,可以break迴圈
- 若前一個index非空,現在的index為空,即將開始新字節,不做事
- 若前一個index為空,現在的index為空,不做事
:boy: 這樣子,如果只有"a"字串會回傳1嗎?
:fish: 阿..因為初始的文字無法與前一個index比較,所以需要多加一個情況。如果初始index是文字的話,則回傳數字就必須再多加1。這樣應該就能符合上述所說情況。
:boy: 沒錯!請你邊實作邊講解一下你的程式碼。
:fish: <開始邊打程式碼邊講解>
:boy: 為甚麼程式是從`s.length() - 1`開始呀?
:fish: 因為string的最後一個index會存放`\0`代表字串的結束,但是這個index並不在word計算字數裡面,因此將他排除。
:boy: 時間差不多了,今天的面試就到這邊,謝謝。
### 程式碼
```cpp=
class Solution {
public:
int lengthOfLastWord(string s) {
int tem = 0;
for(int i=s.length()-1;i>0;i--)
{
if(s[i] == ‘ ‘ && s[i-1] == ‘ ‘)
{
continue;
}
else if(s[i] != ‘ ‘ && s[i-1] == ‘ ‘)
{
tem++;
}
else if(s[i] != ‘ ‘ && s[i-1] != ‘ ‘)
{
tem++
}
else if(s[i] == ‘ ‘ && s[i-1] != ‘ ‘)
{
break;
}
}
if(s[0]!=’ ‘)
{
tem++;
}
return tem;
}
};
```
## 初步檢討自己的表現
1. 面試者出題時,題目與題目之間沒有連貫性
2. 還無法做到一邊講解,一邊打程式
3. 未留意程式間的{}
#### 參考資料
- [vector相關操作](https://www.uj5u.com/qita/272616.html)
----
# 第三次作業-他評
## Interviewer
## Interviewee
- 語速和語氣很像在背課文,連用三倍速聽起來都有點卡卡的 QQ
# 第三次作業-他評02
## 優點
* 有重複問題和舉例討論
## 缺點
### [66. Plus One](https://leetcode.com/problems/plus-one/)
[00:14](https://youtu.be/_eIbSRmkFKo?t=14) Interviewer的提問和後面的問題沒有關聯?
[00:16](https://youtu.be/_eIbSRmkFKo?t=16) lvalue在C99規格書定義是`locator value`,rvalue也不是right value,所以不應將兩者的中文翻為左值或右值。
[00:49](https://youtu.be/_eIbSRmkFKo?t=49) Interviewee舉例時如果已經分享螢幕畫面給Interviewer,可以直接在說明時將範例打在文件上。
[01:02](https://youtu.be/_eIbSRmkFKo?t=62) post increment應該是回傳一個與舊值相等之暫時複製再對原變數+1,由於無法對此回傳做dereference,所以是rvalue,不是先賦值給x再+1。
[01:51](https://youtu.be/_eIbSRmkFKo?t=111) Interviewee的舉例應該直接考慮特殊情況(例如因為進位而多一位數),比較能展現對特殊情況的敏感度。
[02:20](https://youtu.be/_eIbSRmkFKo?t=140) Interviewee討論最低位數遇到9的情況時,由於前面舉例跟這個無關,應該另外打字列出。
[03:00](https://youtu.be/_eIbSRmkFKo?t=180) Interviewee不用特地將舉例刪掉。
[04:47](https://youtu.be/_eIbSRmkFKo?t=287) `i == 0`只會發生在最後,不需要每次進入迴圈都判斷,另外也忘了做進位。
[05:31](https://youtu.be/_eIbSRmkFKo?t=331) Interviewer說最上面的條件都不符合太含糊了,看不出來是因為甚麼特別的輸入,才需要回傳包含-1的vector。
[05:40](https://youtu.be/_eIbSRmkFKo?t=287) Interviewer突然改問vector.insert()底層怎麼實作怪怪的,應該是針對題目本身做延伸,例如:代表數字的輸入vector可以是負的,或者變成Linked List要怎麼處理。
### [58. Length of Last Word](https://leetcode.com/problems/length-of-last-word/)
[06:45](https://youtu.be/_eIbSRmkFKo?t=405) 跟前面一樣,Interviewer的提問和接著要問的問題無關。
[07:04](https://youtu.be/_eIbSRmkFKo?t=424) $\{\}$應該是大括號不是中括號,然後char array沒有一定要在最後補`\0`。(使用情境要有明確假設)
[08:56](https://youtu.be/_eIbSRmkFKo?t=536) Interviewee講的條件比較多時,應該搭配游標或打字說明,不然Interviewer可能無法馬上吸收並理解Interviewee的想法。
[12:54](https://youtu.be/_eIbSRmkFKo?t=774) Interviewee的做法`if (s[0]!= ' ')`有問題。假如字串中包含超過一個word,`s[0]`又非空白時長度就會多算。若要解決Interviewer提出只有一個字元該怎麼辦的問題,應該將判斷移到for迴圈前面,並改寫成
```c=
if (s.size() == 1 && s[0] != ' ')
return 1;
```
[13:49](https://youtu.be/_eIbSRmkFKo?t=829) 取`i = string.length() - 1`跟`\0`無關(C++ string也並非以\0判斷是否為結尾),而是因為索引值的範圍從`0`到`string.length() - 1`。
[14:07](https://youtu.be/_eIbSRmkFKo?t=847) Interviewee一開始取的整數型別變數名稱`tem`可以改叫`len`之類的,和結果比較有關連。另外這題可以不用一直判斷前後是否為空(直接從字串的尾端開始,先找到第一個非空白字元,再往前找到下個空白,兩者相減即可)。因此Interviewer最後應該適時給予提示並要求改進。
* Interviewer和Interviewee整體的對談太像是在念一對一考試的劇本,不夠自然。
* 大括號能省則省,節省寫程式的時間。
# 第三次作業-他評03
雖然說聲音比較低的是 interviewer,比較高的是 interviewee,但有時候聽不太出來差異
## Interviewer
- [1:26](https://youtu.be/_eIbSRmkFKo?t=86) 題目內容與 l value 和 r value 的相關性不強
- [7:19](https://youtu.be/_eIbSRmkFKo?t=439) 詢問一些比較細節的,確認 interviewee 的理解程度,不錯
- [13:39](https://youtu.be/_eIbSRmkFKo?t=819) 聽不出來 interviewer 是出於什麼原因詢問這個問題
## Interviewee
- [0:36](https://youtu.be/_eIbSRmkFKo?t=36) 講話可以帶有一些贅字,聽起來比較不會太吃力,可以用等號左邊和等號右邊來取代左值右值
- [0:50](https://youtu.be/_eIbSRmkFKo?t=50) 可以將舉例融合在前面陳述時直接打在 codepad 上
- [1:57](https://youtu.be/_eIbSRmkFKo?t=117) 一邊重複陳述確認題目,一邊示例,good
- [4:08](https://youtu.be/_eIbSRmkFKo?t=248) 隨著思考邏輯寫程式,很容易理解
# 第三次作業 - 他評04
## 總體評價
Interviewee/Interviewer 雙方完全就是在朗讀,以對方的視角來說,聽到『則將 XXX 設為 0,並往更高位數探討之。...』,我不會覺得他是在回答我的問題而是在背課文。
## 第一題:
+ `lvalue` 和 `rvalue` 的差別這個問題本身就有問題。在
- Interviewer 使用的詞是 `lavlue` 和 `rvalue`,Interviewee 不應該擅自更改成『左值』與『右值』。
- `lvalue`,`rvalue` 等並不是一個「值」,而是 Expression 的分類。
- [這份文件的 3.10 Lvalues and rvalues](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf) 有更詳細的說明。
- 假設 `x` 是一個 object,`++x` 並也可能被 overload 成一個 `lvalue`,`xvalue` 或 `prvalue`。問這種問題應該要提供 `x` 的 type,若是一個自定義的 class 也應該提供 overload, constructor 和 deconstructur 的實作。
- 這個問題跟需要解的題目完全沒有關聯。
+ Interviewer 說話太卡,會讓 Interviewee 懷疑 Interviewer 是不是根本不知道自己在考什麼。
+ `vector<T>.insert()` 的實做我認為是個不太適當的問題。簡單來說可以看做是『在一個 Linked List 中插入一個額外的 node』。
- Interviewer 回答了迭代器操作,卻沒有回答 vector 的實作方式。這樣鐵定會被問『那,迭代器是什麼?』 『position 迭代器又是什麼』
+ **Iterator 不是指標!!!!!!!!!!!!!:angry:**
## 第二題
+ <span style="color:green">String 和 `char` array 的差異我就覺得是個很好的問題。如果沒有平常就玩 `<string.h>` 的習慣其實說不太出來,我覺得。</span>
- 然而回答有點不盡人意。以中括號賦值聽起來很像 `char arr = [apple]`,我的意見是該稱為『對 array 賦值』。以雙引號更奇怪,應該說『string literal』。
- `\0` 應叫做 "null character".
- 並非『不知道字串結束』,而是 `\0` 代表的是字串終結,有點反果為因。
+ <span style="color:green">有詢問到 blue 後方的空格滿可以體現對題目例外的敏銳度。</span>
+ 『index 為空,則可以 break 字節』已經是兩岸三地一心同體了,用詞應該統一。
+ 例外條件的對應沒有解釋到為什麼加一可以解決問題。
+ 『為什麼要從 `str.lenth() - 1` 開始迴圈』也跟 null character 不太相關。`std::string str = "apple"; str.length()` 的確會得到 5,但減一的理由僅僅是因為 string 是 0-indexed,不會有 5 這一格。
- **再者,`std::string` 根本就不是 null-terminated.**
- `std::string` 儲存的是字串長以及字串值,`\0` 在 C++ 中並不會讓字串結束。例如:
```c++
int main(){
string str;
str[0] = '\0';
cout << str << "\n";
return 0;
}
```
- 會輸出
```shell
esting
```
# 第三次作業-他評04
> 到中間就不太能夠分辨哪段是interviewer, 哪段是interviewee
## interviewer
* [0:11](https://youtu.be/_eIbSRmkFKo?t=11) 沒有前後文描述就直接提問R value 跟 L value的定義,問法有點怪(憑空問問題的感覺)。
## interviewee
* [0:29](https://youtu.be/_eIbSRmkFKo?t=29) 對於interviewer的問題沒有確認就直接回覆,回覆內容也有許多東西沒有先說明清楚
* [1:06](https://youtu.be/_eIbSRmkFKo?t=66) 程式碼直接用唸的有點難反應過來,打在doc上可能會比較好理解
* [4:18](https://youtu.be/_eIbSRmkFKo?t=258) 開始寫程式碼後太多沒有聲音的時間,可以在寫Code的時候稍微注意排版就不用一直縮排