本魯為碩士鳳梨大學 CS,大學為雞肉飯大學CS....
佳能(ability)-軟韌體工程師
在五股區的佳能,到了之後先到四樓找總機小姐,戴上訪客證後就被人資帶走了。
專業科目主要考C的pointer、thread,還有一些常識性的計算題,加上英文測驗跟適性測驗,題目不多,穩穩寫能寫完。寫完後人資小姐先進來開始要求我作3分鐘自我介紹,人資小姐有裝出專業的樣子,但我不知道自己自介裡講的那些專業術語,她聽不聽得懂,說不定我唬爛她也聽不出來XD。總之她問的問題還是圍著我準備的自傳打轉。之後輪到主管來面試,主管人很好,問的問題也很輕鬆寫意,有點專業又有點輕鬆,當然也問了一些面試常見的問題像是為何想來這家公司面試之類的,問了自己最在乎的工時問題,主管給人回答的感覺是還好,不會很操。
普安-軟韌體工程師
到了公司上了八樓,被櫃檯小姐帶到會議室,之後正妹人資小姐就進來了簡單問一下自傳上的問題,接著寫了張C語言的考卷,內容約為pointer、union、struct、sizeof的應用,其他還有位元計算(and、or) ,字串串接,how to make the function re-enterable(完全不懂這題在問什麼)
,debug的技巧有哪些,deadlock是什麼,race condition,考完後主管進來就直接照著自傳上發問,然後檢討考卷(天殺的,我完全不會),不過主管還是很有耐心陪我每題每題看完XD,接下來就問一下生活化的問題,像是鳳梨大學如何如何之類的,很生活化的問題,結束時人資還送給我一個小禮物(難不成是安慰獎?)
系微科技-Linux/Android 軟體工程師
到了公司上了12樓,跟櫃台小姐打招呼,櫃台小姐酷酷的,不怎麼理人
被人資帶進會議室後就開始寫考卷,專業題目C部份都挺簡單的,java考了三題
印象中一題是考final、finally、finallize的差別,然後像是按下電源後boot的程序,一題簡單的linking-list,process跟thread的差別,static 跟 dynamic libary的差別,考了兩小時人資進來宣布我專業沒及格,只好有點冏的離開了
威盛電子
我參加的是威盛電子研發替代役台北場,場面弄的像是碩士班推甄一樣。我報到之後就被親切的人資小姐帶走參加第一場面試,職位是BIOS Firmware Engineer/Android Engineer,主管請我自介後就開始介紹他們部門在作什麼,聊的都是挺輕鬆的話題。第二場面試是Cloud Software Engineer,這場面試也是挺輕鬆的,連自介都沒有,主管就照著我帶過去的自傳發問。結束後就先被人資帶進休息室吃便當(中午居然有便當,真感動)。第三場面試是Graphics Software Engineer,自介後,面試官也問了幾個專業問題,便向我表示他也是中正畢業在當研發替代役的學長XD,學長表示在威盛工作CP值挺高的,雖然不是一流公司,但工作壓力不大,主管人也不錯,每天7、8點下班,晚上公司提供免費便當。
感想: 雖然威盛在PTT板上負評居多,但實際走一趟後發現威盛電子的裝潢是目前有去面試的公司中,最有科技感的公司。男廁小便斗間都有隔板擋住,而目前有去面試的其他公司都沒有設隔板,因為我很在意這點,怕連小便都有壓力,因為放輕鬆的小便是我的小確幸XD。人資也很親切,主管都很禮遇面試者,公司感覺氣氛不錯,最重要的是還有中正畢業的學長加持,讓我很想研替上這間。
光寶科技-SSD韌體工程師
位於內湖科技園區的光寶科技,大樓非常有氣勢,女生打扮都非常OL,有點不習慣,這家人資訊給我的交通資訊寫得不太清楚,讓我有點怒,明明公車就能直達瑞光路,信上居然寫在花市站下車...,不過後來知道她也是中正畢業的,決定原諒她。將智力測驗跟英文測驗痛苦的寫完後,開始C語言專業測驗,記得有考volatile,還有給一段程式碼看會有什麼潛在的危險。後來兩位面試官進來,兩位面試官進來都強調是閒談,不會看重測驗成績部分,他們想看的是態度,並且一再說明進來這部門是新部門,要做這份工作需要非常好的團隊合作的熱忱,而不是把自己該做的做完就沒事了,要大家同進退。結論就是相當的操,著實有被嚇到。結束面談從公司出來已經6點,交通真的超級打結的阿,公車卡在路上,而路上機車則鑽來鑽去,看起來很危險。
資拓宏宇-程式設計師
這家在板橋火車站樓上,進去還巧遇大學同學,這家要分兩次,第一次集體考試,考邏輯測驗、英文能力、專業考試,從兩點考到四點半,之後人資開始介紹公司,大體來講就是會看專案性質而在不同的辦公室工作,工作還會需要到客戶去做需求分析,也就是說會跑來跑去,薪水大約三萬八到四萬二,有加班費,考試過了就可以進行第二次面試
廣明光電-SSD韌體工程師
這家在龜山華亞工業園區內,對面就是母公司-廣達電腦,進去公司之後看到一位正到驚為天人的櫃台總機,之後在旁邊玩了一下平板後,另一位人資小姐就來引我去面試,首先寫了個性測量表,之後寫了一張英文考卷(無聽力),然後專業測驗,專業考題難易度偏簡單,花了比較多時間在寫一題linklist,主要就是寫兩個function,一個增加Node,一個刪減Node,然後再用自己寫的function去做數字排序,人資跟主管都只是簡單的照著簡歷問了一下問題,沒有自介,後來人資有說明公司福利,年終2個月,每年一次績效獎金分紅,晚餐加班有補助50元
致茂電子-軟體工程師
這家在龜山華亞工業園區內,早上九點的面試,出門就在一直下雨,註定了是一個悲劇的開始,狼狽的到了公司後就開始進行智力測驗,然後專業測驗,測驗較難部分就是要解釋封裝、繼承、多型、類別、物件,然後分別寫出他們的範例程式並且實際應用,之後就開對人資的面試,首先是悲劇的自介,講得非常不順,然後被問了一些問題,順便講了公司的福利,就跟廣明光電差不多,最後要我用幾句話推薦自己,對天生自卑難自棄的我實在悲劇到不行,之後主管進來也是要我自介,第二次自介就稍微順了點,不過主管也是個不善於表達的人,講來講去實在沒有交集,最後草草結束面試,下雨騎車回去怒吃食物結束這場不愉快的面試。
感言: 面試從9月到12月,總共面試了八間,也累積了不少感想,有的公司需要進行智力測驗,智力測驗都有時間限制就相當需要專注力,幾間公司都在致力測驗就被刷掉了,讓我了解自己專注力的不足,英文測驗也是很需要專注力,然後就是專業測驗,最常考的就是C、C++,這些要不要準備就真的看個人選擇,畢竟準備了也不一定會考到,然後是自介,朋友有上中華電信正2提供的方式是說會準備投影片,當天就帶著筆電去自介,這真的是個好方法,絕對比自己憑一張嘴在嘴砲強一百萬倍,以後還有面試絕對要試試,剩下的就是反應力了,例如要你在白板寫一個字串反轉的程式,腦袋運轉不起來就真的GG,然後面試了八間公司也讓我了解到自己想做的工作是什麼,因為研發替代役要做三年,我可不想做一個需要操三年的工作,就算拿了很多錢也沒命花,公司穩定也很重要的,在哪家公司工作反而是其次。再來考慮其次,如果說錢多事少離家近三點都滿足是全域最佳解,那滿足其中兩點就是區域最佳解,而我想能做這樣的工作也沒什麼好抱怨的了,這三年的時間也要記得好好充實自己,等到三年後另外一個人生的交叉點來臨時,讓自己有更多更好的選擇
最後選擇了廣明光電
原因是因為這家符合我的區域最佳解
雖然錢少少(42K)
事少少(平均八小時,有補休)
離家近(住家裡)
福利不錯(廣達的休閒設施都能用)
加上寫SSD的韌體有相當具挑戰性(演算法效能很重要)
寫在這裡提醒自己以後別看到別人做好的工作就一直心理不平衡
自己做的工作已經很符合自己的期待了
別忘了!!!
2014年9月26日 星期五
2014年1月21日 星期二
LZW解碼(dictionary decoding)
延續上一篇文章
此程式為解碼用
BEGIN
s = NIL;
while not EOF
{
k = next input code;
entry = dictionary entry for k;
if (entry == NULL)
entry = s + s[0];
output entry;
if (s != NIL)
add string s + entry[0] to dictionary with a new code;
s = entry;
}
END
input = 1 4 4 2 7 3 3
s k entry/output code string
--------------------------------------
1 A
2 B
3 C
--------------------------------------
NIL 1 A
A 4 A 4 AA
A 4 AA 5 AA
AA 2 B 6 AAB
B 7 BB 7 BB
BB 3 C 8 BBC
C 3 C 9 CC
C eof
output = AAAABBBCC
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
int main( void )
{
vector<int> code; //向量code儲存碼
vector<string> str; //向量str儲存string
string input,s,entry;
char c;
int j,i=1,search_result,k;
stringstream input_num;
fstream file1,file2;
file1.open("input.txt"); //input為檔案資料輸入
file2.open("output.txt"); //output為檔案資料輸出
if(!file1 || !file2)
cout << "檔案開啟失敗";
//先將A B C 寫入字典
str.push_back("A");
code.push_back(1);
str.push_back("B");
code.push_back(2);
str.push_back("C");
code.push_back(3);
//解碼開始
while(1)
{
while(1) //讀取code 直到遇到空白停下
{
c = file1.get();
if( c == ' ' || file1.eof() )
break;
else
input = input + c;
}
input_num << input; //進行string轉成int的轉換
input_num >> k;
input_num.clear();
input.clear();
search_result = 0;
for(j=0;j<str.size();j++)
{
if( k == code[j] )
{
search_result = 1; //字典裡已有這個碼
entry = str[j];
break;
}
}
if( search_result == 0 ) //字典裡沒有這個碼
entry = s + s[0];
file2 << entry;
if( i != 1 )
{
str.push_back(s+entry[0]);
code.push_back(code.size()+1);
}
i=2;
s = entry;
if(file1.eof())
break;
}
//解碼結束
system("pause");
return 0;
}
此程式為解碼用
BEGIN
s = NIL;
while not EOF
{
k = next input code;
entry = dictionary entry for k;
if (entry == NULL)
entry = s + s[0];
output entry;
if (s != NIL)
add string s + entry[0] to dictionary with a new code;
s = entry;
}
END
input = 1 4 4 2 7 3 3
s k entry/output code string
--------------------------------------
1 A
2 B
3 C
--------------------------------------
NIL 1 A
A 4 A 4 AA
A 4 AA 5 AA
AA 2 B 6 AAB
B 7 BB 7 BB
BB 3 C 8 BBC
C 3 C 9 CC
C eof
output = AAAABBBCC
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
int main( void )
{
vector<int> code; //向量code儲存碼
vector<string> str; //向量str儲存string
string input,s,entry;
char c;
int j,i=1,search_result,k;
stringstream input_num;
fstream file1,file2;
file1.open("input.txt"); //input為檔案資料輸入
file2.open("output.txt"); //output為檔案資料輸出
if(!file1 || !file2)
cout << "檔案開啟失敗";
//先將A B C 寫入字典
str.push_back("A");
code.push_back(1);
str.push_back("B");
code.push_back(2);
str.push_back("C");
code.push_back(3);
//解碼開始
while(1)
{
while(1) //讀取code 直到遇到空白停下
{
c = file1.get();
if( c == ' ' || file1.eof() )
break;
else
input = input + c;
}
input_num << input; //進行string轉成int的轉換
input_num >> k;
input_num.clear();
input.clear();
search_result = 0;
for(j=0;j<str.size();j++)
{
if( k == code[j] )
{
search_result = 1; //字典裡已有這個碼
entry = str[j];
break;
}
}
if( search_result == 0 ) //字典裡沒有這個碼
entry = s + s[0];
file2 << entry;
if( i != 1 )
{
str.push_back(s+entry[0]);
code.push_back(code.size()+1);
}
i=2;
s = entry;
if(file1.eof())
break;
}
//解碼結束
system("pause");
return 0;
}
LZW編碼(dictionary coding)
LZW編碼是資料壓縮的一種方法
以下是LZW的演算法及簡單實作出LZW編碼的程式
BEGIN
s = next input character;
while not EOF
{
c = next input character;
if s + c exists in the dictionary
s = s + c;
else
{
output the code for s;
add string s + c to the dictionary with a new code;
s = c;
}
}
output the code for s;
END
input = ABABBABCABABBA
s c output code string
--------------------------------
1 A
2 B
3 C
---------------------------------
A B 1 4 AB
B A 2 5 BA
A B
AB B 4 6 ABB
B A
BA B 5 7 BAB
B C 2 8 BC
C A 3 9 CA
A B
AB A 4 10 ABA
A B
AB B
ABB A 6 11 ABBA
A EOF 1
output = 1 2 4 5 2 3 4 6 1
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace std;
int main( void )
{
vector<int> code; //向量code儲存碼
vector<string> str; //向量str儲存string
string input,s,c,temp;
int j,i=1,search_result;
fstream file1,file2;
file1.open("input.txt"); //input為檔案資料輸入
file2.open("output.txt"); //output為檔案資料輸出
if(!file1 || !file2)
cout << "檔案開啟失敗";
else
file1 >> input; //讀進檔案裡的資料後 寫入input
//先將A B C 寫入字典
str.push_back("A");
code.push_back(1);
str.push_back("B");
code.push_back(2);
str.push_back("C");
code.push_back(3);
//編碼開始
s = input[0];
while(1)
{
c = input[i++];
temp = s + c;
for(j=0;j<str.size();j++)
{
if(temp == str[j]) //temp已在字典裡
{
s = s + c;
search_result = 1;
break;
}
search_result = 0; //temp不再字典裡
}
if( search_result == 0 )
{
for(j=0;j<str.size();j++)
{
if( s == str[j] )
{
file2 << code[j] << " ";
break;
}
}
str.push_back(temp);
code.push_back(code.size()+1);
s = c;
}
if( i == input.size() )
break;
}
for(j=0;j<str.size();j++)
{
if( s == str[j] )
file2 << code[j];
}
//編碼結束
system("pause");
return 0;
}
以下是LZW的演算法及簡單實作出LZW編碼的程式
BEGIN
s = next input character;
while not EOF
{
c = next input character;
if s + c exists in the dictionary
s = s + c;
else
{
output the code for s;
add string s + c to the dictionary with a new code;
s = c;
}
}
output the code for s;
END
input = ABABBABCABABBA
s c output code string
--------------------------------
1 A
2 B
3 C
---------------------------------
A B 1 4 AB
B A 2 5 BA
A B
AB B 4 6 ABB
B A
BA B 5 7 BAB
B C 2 8 BC
C A 3 9 CA
A B
AB A 4 10 ABA
A B
AB B
ABB A 6 11 ABBA
A EOF 1
output = 1 2 4 5 2 3 4 6 1
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace std;
int main( void )
{
vector<int> code; //向量code儲存碼
vector<string> str; //向量str儲存string
string input,s,c,temp;
int j,i=1,search_result;
fstream file1,file2;
file1.open("input.txt"); //input為檔案資料輸入
file2.open("output.txt"); //output為檔案資料輸出
if(!file1 || !file2)
cout << "檔案開啟失敗";
else
file1 >> input; //讀進檔案裡的資料後 寫入input
//先將A B C 寫入字典
str.push_back("A");
code.push_back(1);
str.push_back("B");
code.push_back(2);
str.push_back("C");
code.push_back(3);
//編碼開始
s = input[0];
while(1)
{
c = input[i++];
temp = s + c;
for(j=0;j<str.size();j++)
{
if(temp == str[j]) //temp已在字典裡
{
s = s + c;
search_result = 1;
break;
}
search_result = 0; //temp不再字典裡
}
if( search_result == 0 )
{
for(j=0;j<str.size();j++)
{
if( s == str[j] )
{
file2 << code[j] << " ";
break;
}
}
str.push_back(temp);
code.push_back(code.size()+1);
s = c;
}
if( i == input.size() )
break;
}
for(j=0;j<str.size();j++)
{
if( s == str[j] )
file2 << code[j];
}
//編碼結束
system("pause");
return 0;
}
RGB_YUV_Extraction
將一張大小為512*512的RAW檔裡的RGB值及YUV值抽取出來各成為一張圖片
其中RAW檔裡資料的排列方式為藍、綠、紅、藍、綠、紅....
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<cmath>
其中RAW檔裡資料的排列方式為藍、綠、紅、藍、綠、紅....
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<cmath>
int main()
{
int i;
FILE *orimage=fopen("desert.raw", "rb"); //輸入檔為一張RAW檔
unsigned char buffer[786432]; //512*512*3
{
int i;
FILE *orimage=fopen("desert.raw", "rb"); //輸入檔為一張RAW檔
unsigned char buffer[786432]; //512*512*3
FILE *blue=fopen("desertRed.raw", "wb");
FILE *green=fopen("desertGreen.raw", "wb");
FILE *red=fopen("desertBlue.raw", "wb");
FILE *y=fopen("deserty.raw","wb");
FILE *u=fopen("desertu.raw","wb");
FILE *v=fopen("desertv.raw","wb");
for( i=0; i<786432; i++)
{
buffer[i] = getc(orimage); //依次讀一個 byte , 三個一組 , 依序存入紅綠藍 三檔案裡
if( (i%3) == 0)
putc(buffer[i],blue);
if( (i%3) == 1)
putc(buffer[i],green);
if( (i%3) == 2)
{
putc(buffer[i],red);
putc( (buffer[i-2]*0.114 + buffer[i-1]*0.587 + buffer[i]*0.299),y); //進行YUV矩陣換算
putc( fabs(buffer[i-2]*0.437 + buffer[i-1]*(-0.289) + buffer[i]*(-0.148)),u);
putc( fabs(buffer[i-2]*(-0.100) + buffer[i-1]*(-0.515) + buffer[i]*0.615),v);
}
}
system("pause");
return 0;
}
FILE *green=fopen("desertGreen.raw", "wb");
FILE *red=fopen("desertBlue.raw", "wb");
FILE *y=fopen("deserty.raw","wb");
FILE *u=fopen("desertu.raw","wb");
FILE *v=fopen("desertv.raw","wb");
for( i=0; i<786432; i++)
{
buffer[i] = getc(orimage); //依次讀一個 byte , 三個一組 , 依序存入紅綠藍 三檔案裡
if( (i%3) == 0)
putc(buffer[i],blue);
if( (i%3) == 1)
putc(buffer[i],green);
if( (i%3) == 2)
{
putc(buffer[i],red);
putc( (buffer[i-2]*0.114 + buffer[i-1]*0.587 + buffer[i]*0.299),y); //進行YUV矩陣換算
putc( fabs(buffer[i-2]*0.437 + buffer[i-1]*(-0.289) + buffer[i]*(-0.148)),u);
putc( fabs(buffer[i-2]*(-0.100) + buffer[i-1]*(-0.515) + buffer[i]*0.615),v);
}
}
system("pause");
return 0;
}
Divide-and-Conquer for Maxima Finding
演算法:
定義: P1(x1,y1) dominate P2(x2,y2) if only if x1 >= x2 and y1 >= y2
A point is called a max point if no other point dominate it
輸入:一些平面上的點
輸出:THE MAXIMAL points
1. if 只有一點, 回傳它就是 max point
不然找一直線L垂直X軸 並且分割S成一半 SL and SR
2. 持續遞迴直到剩下兩點或一點, 進行比較
3. 開始merge, 在SR裡找到一點有最大的Y值,記錄它,
並且在SL裡判斷所有的點的Y值有沒有小於這點的Y,
如果有,刪除這點
程式碼實作如下
#include <stdio.h>
#include <stdlib.h>
struct vertex //座標資料
{
int x; //紀錄X位置
int y; //紀錄Y位置
int max_point; //紀錄是否為max_point
};
void per( struct vertex *vertex_arr1, int init, int end) //per函式將所有點一分為二 init為初始注標 end為結尾注標
{
int i,maxy=0,maxx=0;
if( init == end ) //if分割到只勝一點 將這點指派為max_point
vertex_arr1[init].max_point = 1;
else
{
per(vertex_arr1, init, (init + end )/2); //分割後 前半段帶入遞迴
//開始merge
for(i=(init + end )/2+1;i<=end;i++) // 找後半段的最大y值的點
{
if( maxy < vertex_arr1[i].y )
{
maxx = vertex_arr1[i].x;
maxy = vertex_arr1[i].y;
}
}
for(i=init;i<=(init + end)/2;i++) // 前半段的點若為max_point 則判斷此點x y值 若小於maxx maxy 則為不合的點
{
if( vertex_arr1[i].max_point == 1 && vertex_arr1[i].x < maxx && vertex_arr1[i].y < maxy )
vertex_arr1[i].max_point = 0;
}
per(vertex_arr1, (init + end )/2+1, end); //分割後 後半段帶入遞迴
}
}
int main(void)
{
int i,max=0,j,temp;
char c[10];
FILE *fp;
fp = fopen("input.txt","r+");
i=0;
while(1) //讀檔
{
i++;
if( fgets(c,10,fp) == NULL )
break;
}
max = i-1; // 算有幾個點
fseek(fp,0L,SEEK_SET); //移回檔頭
struct vertex *vertex_arr = malloc( max * sizeof(struct vertex) );
for(i=0;i<max;i++) //初始化
{
vertex_arr[i].x = -1;
vertex_arr[i].y = -1;
vertex_arr[i].max_point = 0;
}
i=0;
while(1) //讀檔 並放入vertex 結構
{
fscanf( fp,"%d,%d",&(vertex_arr[i].x) ,&(vertex_arr[i].y) );
i++;
if( getc(fp) == EOF )
break;
}
//先按照X值由小到大排列
for(i=0;i<max;i++)
{
for(j=i+1;j<max;j++)
{
if( vertex_arr[i].x > vertex_arr[j].x )
{
temp = vertex_arr[i].x;
vertex_arr[i].x = vertex_arr[j].x;
vertex_arr[j].x = temp;
temp = vertex_arr[i].y;
vertex_arr[i].y = vertex_arr[j].y;
vertex_arr[j].y = temp;
}
}
}
per(vertex_arr,0,max-1); //開始遞迴
for(i=0;i<max;i++) //印出max_point
{
if( vertex_arr[i].max_point == 1 )
printf("%d,%d\n",vertex_arr[i].x ,vertex_arr[i].y);
}
system("pause");
return 0;
}
輸入請以讀入檔案方式。
例如:以下檔案內容,代表5個平面座標點
2,3
4,5
6,7
8,9
10,11
訂閱:
文章 (Atom)