最近身邊很多人在找工作,漫多公司會有考試以及口試中會有技術問答的部分。
以不碰硬體的軟體工程師來說,技術問題我簡略的分成兩類:
偏硬的公司,比較會問記憶體位址相關的問題,如指標、參考等這些一般人比較容易搞不清楚的觀念。
偏軟的公司,比較會問物件導向相關的問題,如物件導向的優點、特性、以及實務上的一些問題。
當然除此之外一些共通的部分像是作業系統或計算機架構,這就看平常在學校有沒有好好學。
我為什麼把問題分成漲兩類呢?因為我發現身旁漫多人可能因為本身習慣的關係,兩種觀念比較無法同時記住。
通常平常很會用指標、參考的人,很可能會對物件導向比較不熟,例如c習慣使用者。
而平常慣用 oop language 的朋友,如 java、c#,則對指標參考等的觀念記憶稍微薄弱一些。
之前有寫過指標類的介紹了,不過似乎有點簡略,之後有空再補完。
今天介紹一下物件導向一些基本概念,這些同時也是找工作筆試面試常會遇到的一些問題。
封裝
我之前都是寫 c# 居多,即使如此,當面試時公司主管問我:物件導向為什麼要封裝?我卻回答的零零落落。
因為平常用的太習慣了,覺得封裝已經是在自然不過的事情,哪需要理由?
基本上這種問題你只要提到 keyword 就好了:
Information hiding, 避免程式各個物件互相干擾,降低程式的複雜度及維護上的困難度。
繼承
繼承的目的:一語概之就是為了 reuse。
多型
多型與超載 (Overloading)與重寫 (Overriding)相關,和上面的繼承更是息息相關。
一個物件如果你看待的方式不同,就可以發揮不同的功用。
這在現實生活中很合理,一個碗可以拿來當容器,也可以拿來盛土種花,當然要倒過來當蓋子也行,甚至,你要拿來砸碎當發聲的樂器也不犯法。
因此同一個物件,在不同的場合,不同的使用情境,就應該合理運作展現應有的效果,這也就是多型的精神。
參考資料:
http://www.ithome.com.tw/itadm/article.php?c=45903
http://140.134.26.7/wbemwiki/index.php/%E7%AC%AC%E4%B8%89%E7%AB%A0_%E7%89%A9%E4%BB%B6%E5%B0%8E%E5%90%91%E8%A8%AD%E8%A8%88
2009年10月22日 星期四
音樂術語
常見的速度術語:
Largo 最緩板 速度♩= 40~60
Larghetto 甚緩板 速度♩= 60~66
Adagio 慢板 速度♩= 66~76
Andante 行板 速度♩= 76~108
Moderato 中板 速度♩=108~120
Allegro 快板 速度♩= 120~168
Presto 急板 速度♩= 168~200
Prestissimo 最急板 速度♩= 200~208
速度漸慢 :
Allargando (allarg.)
Rallentando (rall.)
Ritardando (rit.)
速度漸快:
Accelerando (accel.)
速度還原:(回到正常的速度)
A tempo
Tempo primo
速度任意:(隨意,由演奏者或指揮者自定)
Ad libitum (ad lib.)
Tempo rubato
常見的力度術語:
Pianisissimo (ppp) 最弱
Pianissimo (pp) 甚弱
Piano (p) 弱
Mezzo piano (mp) 中弱
Mezzo forte (mf) 中強
Forte (f) 強
Fortissimo (ff) 甚強
Fortisissimo (fff) 最強
補充:fp 強後立即轉弱 sf.、sfz.、rf.、rfz.、rinf.皆為突強
漸強:
Crescendo (cresc.)
漸弱:
Decrescendo (decresc.)
Diminuendo (dim.)
Largo 最緩板 速度♩= 40~60
Larghetto 甚緩板 速度♩= 60~66
Adagio 慢板 速度♩= 66~76
Andante 行板 速度♩= 76~108
Moderato 中板 速度♩=108~120
Allegro 快板 速度♩= 120~168
Presto 急板 速度♩= 168~200
Prestissimo 最急板 速度♩= 200~208
速度漸慢 :
Allargando (allarg.)
Rallentando (rall.)
Ritardando (rit.)
速度漸快:
Accelerando (accel.)
速度還原:(回到正常的速度)
A tempo
Tempo primo
速度任意:(隨意,由演奏者或指揮者自定)
Ad libitum (ad lib.)
Tempo rubato
常見的力度術語:
Pianisissimo (ppp) 最弱
Pianissimo (pp) 甚弱
Piano (p) 弱
Mezzo piano (mp) 中弱
Mezzo forte (mf) 中強
Forte (f) 強
Fortissimo (ff) 甚強
Fortisissimo (fff) 最強
補充:fp 強後立即轉弱 sf.、sfz.、rf.、rfz.、rinf.皆為突強
漸強:
Crescendo (cresc.)
漸弱:
Decrescendo (decresc.)
Diminuendo (dim.)
拿Google Reader看PTT
1.
到 http://www.google.com/reader 登入
2.
左上角有個新增訂閱 按下去
填入你要看的看板
格式是 rss.ptt.cc/看板名稱.xml
例如笨版 就打 rss.ptt.cc/StupidClown.xml
注意大小寫要完全一樣
3.
完成 上班可以逛PTT了= =+
參考資料:http://ipluto.wordpress.com/2009/07/31/%E6%8B%BFgoogle-reader%E7%9C%8Bptt/
2009年10月21日 星期三
C++ 簡易速查
Virtual Function
虛擬函數
虛擬函數會以關鍵字 virtual 為首宣告在基底類別。用途為供其衍生類別各自實作所需的同名成員函數。
ex.
Pure Virtual Function
單純虛擬函數
為虛擬函數的一種,其宣告方式為 virtual return_type function_declaration (parameter) = 0;
ex.
Abstract Class
抽象類別
含有虛擬函數宣告的類別即為抽象類別,所以上述面舉的兩個例子中的 MyClassVF、MyClassPVF 都是。
Boxing and Unboxing
裝箱、拆箱
Boxing 將實值類別轉換成 object 類別。
Unboxing 將 object 類別轉換成實值類別。
參考資料:http://msdn.microsoft.com/zh-tw/library/yz2be5wk.aspx
ex.
Tracking Handles
追蹤處理
Tracking Handle 有點像是指標,其內容也是存一個位址。
宣告方式為 type^ variable_name;
不過和指標不一樣的是,他的位址是由垃圾回收者自動更新。
換句話說,手動調整 Tracking Handle 的位址是不被允許的。
還有,和指標一樣,在宣告 Tracking Handle 時,他是不指向任何位址的。
因此,任何的參考前都必須先作指定初始位址的動作。
ex.
L"...."
將 "..." 轉換為 unicode。
stdafx.h
參考文件:http://zhidao.baidu.com/question/3711602.html
Using Enumerators as Flags
一個很實用的技巧,不過只有在 C++/CLI 底下才能用。ANSI C++ 並不支援。
參考資料:Beginning Visual C++ 2008[Ivor Horton]
ex.
output:
虛擬函數
虛擬函數會以關鍵字 virtual 為首宣告在基底類別。用途為供其衍生類別各自實作所需的同名成員函數。
ex.
class MyClassVF {
public:
virtual int myfunc ()
{ return 0; }
};
Pure Virtual Function
單純虛擬函數
為虛擬函數的一種,其宣告方式為 virtual return_type function_declaration (parameter) = 0;
ex.
class MyClassPVF {
public:
virtual int myfunc (void) = 0;
};
Abstract Class
抽象類別
含有虛擬函數宣告的類別即為抽象類別,所以上述面舉的兩個例子中的 MyClassVF、MyClassPVF 都是。
Boxing and Unboxing
裝箱、拆箱
Boxing 將實值類別轉換成 object 類別。
Unboxing 將 object 類別轉換成實值類別。
參考資料:http://msdn.microsoft.com/zh-tw/library/yz2be5wk.aspx
ex.
int i = 123; // a value type
object o = i; // boxing
int j = (int)o; // unboxing
Tracking Handles
追蹤處理
Tracking Handle 有點像是指標,其內容也是存一個位址。
宣告方式為 type^ variable_name;
不過和指標不一樣的是,他的位址是由垃圾回收者自動更新。
換句話說,手動調整 Tracking Handle 的位址是不被允許的。
還有,和指標一樣,在宣告 Tracking Handle 時,他是不指向任何位址的。
因此,任何的參考前都必須先作指定初始位址的動作。
ex.
String^ sentence;
sentence = nullptr; // set handle to null
sentence = "This is a sentence.";
int^ value = 0; // initialization
*value = 100;
L"...."
將 "..." 轉換為 unicode。
stdafx.h
參考文件:http://zhidao.baidu.com/question/3711602.html
Using Enumerators as Flags
一個很實用的技巧,不過只有在 C++/CLI 底下才能用。ANSI C++ 並不支援。
參考資料:Beginning Visual C++ 2008[Ivor Horton]
ex.
[Flags] enum class FlagBits{ Ready = 1, ReadMode = 2, WriteMode = 4, EOF = 8, Disabled = 16};
FlagBits status = FlagBits::Ready | FlagBits::ReadMode | FlagBits::EOF;
Console::WriteLine(L”Current status: {0}”, status);
output:
Current status: Ready, ReadMode, EOF
2009年10月19日 星期一
winsck example
底下是一個簡單的winsck範例
之前雖然在linux上寫過不過為了測試這個也是花了不少時間
環境:win xp, visual studio express
基本上寫程式這種東西....幾個簡單的東西try通之後,靠的就是想像力和組織能力啦
雖說萬事起頭難,不過東拼西湊完之後的測試,花的時間也是不容小覷
之前雖然在linux上寫過不過為了測試這個也是花了不少時間
環境:win xp, visual studio express
基本上寫程式這種東西....幾個簡單的東西try通之後,靠的就是想像力和組織能力啦
雖說萬事起頭難,不過東拼西湊完之後的測試,花的時間也是不容小覷
#include
#include
#include
#include
#pragma comment(lib, "Wsock32.lib")
#define MAXLINE 1024
int main() {
SOCKET recv_sd, send_sd;
int cli_len, n, sendtoRet, bindRet, errno;
char str[MAXLINE];
struct sockaddr_in recv_addr, send_addr;
WSADATA wsadata;
if (WSAStartup(0x101, (LPWSADATA) &wsadata) != 0) {
fprintf(stderr, "echo_serv: can't use WinSock DLL\n");
exit(1);
}
if ( (recv_sd = socket(AF_INET, SOCK_RAW, 0)) == SOCKET_ERROR) {
fprintf(stderr, "echo_serv: can't open TCP socket\n");
exit(1);
}
if ( (send_sd = socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR) {
fprintf(stderr, "echo_serv: can't open UCP socket\n");
exit(1);
}
// set dst address to broadcast
memset(&send_addr, 0, sizeof send_addr);
send_addr.sin_family = AF_INET;
send_addr.sin_port = 1000;
bindRet = bind(send_sd, (struct sockaddr *)&send_addr, sizeof send_addr);
setsockopt( send_sd, SOL_SOCKET, SO_BROADCAST, "TRUE", 4 );
memset(&send_addr, 0, sizeof send_addr);
send_addr.sin_family = AF_INET;
send_addr.sin_port = 68;
send_addr.sin_addr.s_addr = inet_addr("255.255.255.255");
strcpy_s(str, 12, "Hello World");
//while(1)
sendtoRet = sendto(send_sd, str, 12, 0, (struct sockaddr *)&send_addr, sizeof send_addr);
printf("%d", WSAGetLastError());
closesocket(recv_sd);
closesocket(send_sd);
return 0;
}
訂閱:
文章 (Atom)