# 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)