# Cyberlink CV
###### tags: `Interviews`
## Interview questions
1. 全連接跟卷積差別在哪?為什麼CV用卷積居多? 優勢是什麼?
捕捉空間特徵?參數可複用減少運算 另外也可捕捉重複特徵?
2. 激勵函數引入非線性的目的是什麼?如果只有線性會怎樣?
實際問題很多情況都非線性,不是能靠線性函數解決 *可以補充sigmoid, tanh, relu, softmax...各自帶來的優點
[without activation function](https://www.analyticsvidhya.com/blog/2020/01/fundamentals-deep-learning-activation-functions-when-to-use-them/)
3. Self supervised learning, GAN, Model compression, Model compression, Knowledge distillation, Image classification, object detection, Super resolution這幾個去分類 你會分幾類?怎麼分?
4. 你處理過最難的bug是什麼?
6. 碩班期間,老闆給你的彈性如何?方向跟方法多少是自己決定的?
7. 有沒有老闆覺得目標或方法可行,但你覺得不可行的時候,怎麼處理和最後結果如何?
8. 做過的專案中的這些模型你是直接使用,還是有做什麼調整嗎?
9. 請簡介一個深度學習模型專案流程,並說明如何評估表現?如果表現不夠好,最可能出問題的地方在哪?應該如何調整?
10. CV相關的議題可以舉出哪些?如果有機會錄取,最想做哪一個?
## Coding test
測驗環境(網站)是**Coderbyte**
### BinaryReversal
1. 給一個string的二進位值要從大的位數開始補滿0到8*N bits 補滿之後再反轉 反轉完再換回10進位
* Key:
a. reverse string : swap記得call by reference, size要size-i-1因為string最後一個位置是'\0'
b. binary有可能超過int大小 所以用long long
c. stoi跟to_string要熟悉
* Test cases:
"47" ->101111-> 00101111->11110100->244
"213" -> 171
"4567" -> 60296
"12" -> 1100 -> 00001100 -> 00110000 -> 48
### My solution
```cpp=
#include <iostream>
#include <string>
#include<math.h>
using namespace std;
void swap(string &s, int a, int b)
{
s[a] = s[a] ^ s[b];
s[b] = s[a] ^ s[b];
s[a] = s[a] ^ s[b];
}
string BinaryReversal(string str) {
cout << str;
cout << endl;
// string to integer
int num = stoi(str);
long long binary = 0, remainder, product = 1;
while (num != 0)
{
remainder = num % 2;
binary += remainder * product;
num = num / 2;
product *= 10;
}
string str1 = to_string(binary);
//complement to 8*N bytes
while (str1.size()%8 != 0)
{
str1 = '0' + str1;
}
//reverse string
for (int i = 0; i < str1.size() / 2; i++)
{
swap(str1, i, str1.size() - i - 1);
}
//bin to decimal
int ans = 0;
int j = 0;
for (int i = str1.size() - 1; i >= 0; i--)
{
if (str1[i] == '1')
{
ans += pow(2, j);
}
j++;
}
return to_string(ans);
}
int main()
{
string str = "4567";
string ans_str = BinaryReversal(str);
cout << ans_str;
return 0;
}
```
### ArrayMatching
2. 一個string array裡面有兩個陣列 要把兩個陣列對應的元素相加(第一個加第一個 第二個加第二個...) 如果陣列不等長 剩下的元素就不用加 然後每個元素相加完的結果用字串表示 元素間要以'-'區隔
* Key:
a. atoi的input format是const char*且只能轉超過single digit的數,char要強轉成const char*,single digit直接char - '0'
b. stoi的input format是const string
* Test case:
["[1, 2, 5, 6]", "[5, 2, 8, 11]"]->6-4-13-17
["[1, 2, 5, 6, 7, 9]", "[5, 2, 8, 11]"]->6-4-13-17-7-9
["[1, 2, 5, 6]", "[5, 2, 8, 11, 7, 9]"]->6-4-13-17-7-9
### My solution
```cpp=
#include "pch.h"
#include <iostream>
#include <string>
#include <string.h>
#include<vector>
using namespace std;
vector<int> strtoArr(string Arr)
{
int tmp = 0;
vector<int> arr;
for (int i = 0; i < Arr.size(); i++)
{
if (Arr[i] != ' '&& Arr[i] != '[')
{
if (Arr[i] != ','&& Arr[i] != ']')
{
tmp = tmp * 10 + (Arr[i] - 48);
}
else
{
arr.push_back(tmp);
tmp = 0;
}
}
}
return arr;
}
string ArrayMatching(string strArr[], int arrLength) {
vector<int> nums;
vector<int> nums2;
nums = strtoArr(strArr[0]);
nums2 = strtoArr(strArr[1]);
string ans;
if (nums.size() > nums2.size())
{
for (int i = 0; i < nums2.size(); i++)
{
nums[i] += nums2[i];
}
for (int j = 0; j < nums.size(); j++)
{
ans += to_string(nums[j]);
if (j != nums.size() - 1)
{
ans += '-';
}
}
//cout<<ans;
return ans;
}
else {
for (int i = 0; i < nums.size(); i++)
{
nums2[i] += nums[i];
}
for (int j = 0; j < nums2.size(); j++)
{
ans += to_string(nums2[j]);
if (j != nums2.size() - 1)
{
ans += '-';
}
}
//cout<<ans;
return ans;
}
}
int main(void) {
// keep this function call here
string A[] = {"[1, 2, 5, 6]", "[5, 2, 8, 11, 7, 9]"};
int arrLength = sizeof(A) / sizeof(*A);
cout << ArrayMatching(A, arrLength);
return 0;
}
```
3. LRU Cache
>Have the function LRUCache(strArr) take the array of characters stored in strArr, which will contain characters ranging from A to Z in some arbitrary order, and determine what elements still remain in a virtual cache that can hold up to 5 elements with an LRU cache algorithm implemented. For example: if strArr is ["A", "B", "C", "D", "A", "E", "D", "Z"], then the following steps are taken:
>
>(1) A does not exist in the cache, so access it and store it in the cache.
(2) B does not exist in the cache, so access it and store it in the cache as well. So far the cache contains: ["A", "B"].
(3) Same goes for C, so the cache is now: ["A", "B", "C"].
(4) Same goes for D, so the cache is now: ["A", "B", "C", "D"].
(5) Now A is accessed again, but it exists in the cache already so it is brought to the front: ["B", "C", "D", "A"].
(6) E does not exist in the cache, so access it and store it in the cache: ["B", "C", "D", "A", "E"].
(7) D is accessed again so it is brought to the front: ["B", "C", "A", "E", "D"].
(8) Z does not exist in the cache so add it to the front and remove the least recently used element: ["C", "A", "E", "D", "Z"].
>Now the caching steps have been completed and your program should return the order of the cache with the elements joined into a string, separated by a hyphen. Therefore, for the example above your program should return C-A-E-D-Z.
### LRUCache
>leetcode : https://leetcode.com/problems/lru-cache/
* key
a. 為了找有沒有出現過->set->但set要刪除特定元素還是要迭代
b. 為了方便pop掉最後一個出現的元素->queue->但queue在迭代每一個元素確認是否出現過要一直pop跟push
c. 最後還是用vector
d. ~~這題雖然medium 但感覺沒前兩題難~~
* Test case
Examples
Input: {"A", "B", "A", "C", "A", "B"}
Output: C-A-B
Input: {"A", "B", "C", "D", "E", "D", "Q", "Z", "C"}
Output: E-D-Q-Z-C
### My solution
```cpp=
#include "pch.h"
#include<string>
#include<vector>
#include <iostream>
using namespace std;
string LRUCache(string strArr[], int arrLength)
{
vector<string> cache;
string tmp, ansStr;
cache.push_back(strArr[0]);
//loop the array and save to cache
for (int i = 1; i < arrLength; i++)
{
//check if cache have 5 objects
if (cache.size() < 5)
{
//check if it exits. if yes, find where is it and swap with last one
int cacheSize = cache.size();
for (int j = 0; j < cacheSize;j++)
{
if (cache[j] == strArr[i])
{
cache.erase(cache.begin()+j);
cache.push_back(strArr[i]);
break;
}
else
{
// if not, push it back
if (j == cacheSize-1)
{
cache.push_back(strArr[i]);
}
}
}
}
//if yes, pop the first one (least use one) and push to the last one
else
{
cache.erase(cache.begin());
cache.push_back(strArr[i]);
}
}
for (int i = 0; i < cache.size(); i++)
{
ansStr += cache[i];
if (i != cache.size() - 1)
{
ansStr += '-';
}
}
return ansStr;
}
int main()
{
string A[] = { "A", "B", "C", "D", "E", "D", "Q", "Z", "C" };
int arrLength = sizeof(A) / sizeof(*A);
string ans = LRUCache(A, arrLength);
//cout << endl;
//cout << ans;
return 0;
}
```
## Reference
[string to array](https://www.geeksforgeeks.org/convert-a-string-to-integer-array-in-c-c/)
[atoi & stoi](https://www.796t.com/content/1548701299.html)
[char to const char to string...](https://blog.csdn.net/rongrongyaofeiqi/article/details/52442169)
[queue iteration](https://stackoverflow.com/questions/1259099/stdqueue-iteration)