A. c++經典面試題及答案
1. C++的類和C裡面的struct有什麼區別?
struct成員默認訪問許可權為public,而class成員默認訪問許可權為private
2. 析構函數和虛函數的用法和作用
析構函數是在對象生存期結束時自動調用的函數,用來釋放在構造函數分配的內存。
虛函數是指被關鍵字virtual說明的函數,作用是使用C++語言的多態特性
3. 全局變數和局部變數有什麼區別?是怎麼實現的?操作系統和編譯器是怎麼知道的?
1) 全局變數的作用用這個程序塊,而局部變數作用於當前函數
2) 前者在內存中分配在全局數據區,後者分配在棧區
3) 生命周期不同:全局變數隨主程序創建和創建,隨主程序銷毀而銷毀,局部變數在局部函數內部,甚至局部循環體等內部存在,退出就不存在
4) 使用方式不同:通過聲明後全局變數程序的各個部分都可以用到,局部變數只能在局部使用
4. 有N個大小不等的自然數(1–N),請將它們由小到大排序.要求程序演算法:時間復雜度為O(n),空間復雜度為O(1)。
void sort(int e[], int n)
{
int i;
int t;
for (i=1; i {
t = e[e[i]];
e[e[i]] = e[i];
e[i] = t;
}
}
5. 堆與棧的去區別
A. 申請方式不同
Stack由系統自動分配,而heap需要程序員自己申請,並指明大小。
B. 申請後系統的響應不同
Stack:只要棧的剩餘空間大於申請空間,系統就為程序提供內存,否則將拋出棧溢出異常
Heap:當系統收到程序申請時,先遍歷操作系統中記錄空閑內存地址的鏈表,尋找第一個大於所申請空間的堆結點,然後將該結點從空間結點鏈表中刪 除,並將該結點的空間分配給程序。另外,大多數系統還會在這塊內存空間中的首地址處記錄本次分配的大小,以便於delete語句正確釋放空間。而且,由於 找到的堆結點的大小不一定正好等於申請的大小,系統會自動將多餘的那部分重新放入空閑鏈表。
C. 申請大小限制的不同
Stack:在windows下,棧的大小是2M(也可能是1M它是一個編譯時就確定的常數),如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。
Heap:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由於系統是用鏈表來存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限於計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。
D. 申請效率的比較:
棧由系統自動分配,速度較快。但程序員是無法控制的。
堆是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便。
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配內存,他不是在堆,也不是在棧是直接在進程的地址空間中保留一快內存,雖然用起來最不方便。但是速度快,也最靈活。
E. 堆和棧中的存儲內容
棧:在函數調用時,第一個進棧的是主函數中後的下一條指令(函數調用語句的下一條可執行語句)的地址,然後是函數的各個參數,在大多數的C編譯器 中,參數是由右往左入棧的,然後是函數中的局部變數。注意靜態變數是不入棧的。當本次函數調用結束後,局部變數先出棧,然後是參數,最後棧頂指針指向最開 始存的地址,也就是主函數中的下一條指令,程序由該點繼續運行。
堆:一般是在堆的.頭部用一個位元組存放堆的大小。堆中的具體內容有程序員安排。
6. 含參數的宏與函數的優缺點
宏: 優點:在預處理階段完成,不佔用編譯時間,同時,省去了函數調用的開銷,運行效率高
缺點:不進行類型檢查,多次宏替換會導致代碼體積變大,而且由於宏本質上是字元串替換,故可能會由於一些參數的副作用導致得出錯誤的結果。
函數: 優點:沒有帶參數宏可能導致的副作用,進行類型檢查,計算的正確性更有保證。
缺點:函數調用需要參數、返回地址等的入棧、出棧開銷,效率沒有帶參數宏高
PS:宏與內聯函數的區別
內聯函數和宏都是在程序出現的地方展開,內聯函數不是通過函數調用實現的,是在調用該函數的程序處將它展開(在編譯期間完成的);宏同樣是;
不同的是:內聯函數可以在編譯期間完成諸如類型檢測,語句是否正確等編譯功能;宏就不具有這樣的功能,而且宏展開的時間和內聯函數也是不同的(在運行期間展開)
7. Windows程序的入口是哪裡?寫出Windows消息機制的流程
Windows程序的入口是WinMain()函數。
Windows應用程序消息處理機制:
A. 操作系統接收應用程序的窗口消息,將消息投遞到該應用程序的消息隊列中
B. 應用程序在消息循環中調用GetMessage函數從消息隊列中取出一條一條的消息,取出消息後,應用程序可以對消息進行一些預處理。
C. 應用程序調用DispatchMessage,將消息回傳給操作系統。
D. 系統利用WNDCLASS結構體的lpfnWndProc成員保存的窗口過程函數的指針調用窗口過程,對消息進行處理。
8. 如何定義和實現一個類的成員函數為回調函數
A.什麼是回調函數?
簡而言之,回調函數就是被調用者回頭調用調用者的函數。
使用回調函數實際上就是在調用某個函數(通常是API函數)時,將自己的一個函數(這個函數為回調函數)的地址作為參數傳遞給那個被調用函數。而該被調用函數在需要的時候,利用傳遞的地址調用回調函數。
回調函數,就是由你自己寫的,你需要調用另外一個函數,而這個函數的其中一個參數,就是你的這個回調函數名。這樣,系統在必要的時候,就會調用你寫的回調函數,這樣你就可以在回調函數里完成你要做的事。
B.如何定義和實現一個類的成員函數為回調函數
要定義和實現一個類的成員函數為回調函數需要做三件事:
a.聲明;
b.定義;
c.設置觸發條件,就是在你的函數中把你的回調函數名作為一個參數,以便系統調用
如:
一、聲明回調函數類型
typedef void (*FunPtr)(void);
二、定義回調函數
class A
{
public:
A();
static void callBackFun(void) //回調函數,必須聲明為static
{
cout<<"callBackFun"<
}
virtual ~A();
};
三、設置觸發條件
void Funtype(FunPtr p)
{
p();
}
void main(void)
{
Funtype(A::callBackFun);
}
C. 回調函數與API函數
回調和API非常接近,他們的共性都是跨層調用的函數。但區別是API是低層提供給高層的調用,一般這個函數對高層都是已知的;而回調正好相反, 他是高層提供給底層的調用,對於低層他是未知的,必須由高層進行安裝,這個安裝函數其實就是一個低層提供的API,安裝後低層不知道這個回調的名字,但它 通過一個函數指針來保存這個回調函數,在需要調用時,只需引用這個函數指針和相關的參數指針。
其實:回調就是該函數寫在高層,低層通過一個函數指針保存這個函數,在某個事件的觸發下,低層通過該函數指針調用高層那個函數。
B. 程序員面試經常被提到的問題
java 程序員常用面試題- -
Java程序員面試三十二問
Java程序員面試三十二問
作者:佚名 來自:未知
第一,談談final, finally, finalize的區別。
第二,Anonymous Inner Class (匿名內部類) 是否可以extends(繼承)其它類,是否可以
implements(實現)interface(介面)?
第三,Static Nested Class 和 Inner Class的不同,說得越多越好(面試題有的很籠統)。
第四,&和&&的區別。
第五,HashMap和Hashtable的區別。
第六,Collection 和 Collections的區別。
第七,什麼時候用assert.
第八,GC是什麼? 為什麼要有GC?
第九,String s = new String("xyz");創建了幾個String Object?
第十,Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
第十一,short s1 = 1; s1 = s1 + 1;有什麼錯? short s1 = 1; s1 += 1;有什麼錯?
第十二,sleep() 和 wait() 有什麼區別?
第十三,Java有沒有goto?
第十四,數組有沒有length()這個方法? String有沒有length()這個方法?
第十五,Overload和Override的區別。Overloaded的方法是否可以改變返回值的類型?
第十六,Set里的元素是不能重復的,那麼用什麼方法來區分重復與否呢? 是用==還是equals()?
它們有何區別?
第十七,給我一個你最常見到的runtime exception.
第十八,error和exception有什麼區別?
第十九,List, Set, Map是否繼承自Collection介面?
第二十,abstract class和interface有什麼區別?
第二十一,abstract的method是否可同時是static,是否可同時是native,是否可同時是
synchronized?
第二十二,介面是否可繼承介面? 抽象類是否可實現(implements)介面? 抽象類是否可繼承實體
類(concrete class)?
第二十三,啟動一個線程是用run()還是start()?
第二十四,構造器Constructor是否可被override?
第二十五,是否可以繼承String類?
第二十六,當一個線程進入一個對象的一個synchronized方法後,其它線程是否可進入此對象的其它
方法?
第二十七,try {}里有一個return語句,那麼緊跟在這個try後的finally {}里的code會不會被執行
,什麼時候被執行,在return前還是後?
第二十八,編程題: 用最有效率的方法算出2乘以8等於幾?
第二十九,兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對
?
第三十,當一個對象被當作參數傳遞到一個方法後,此方法可改變這個對象的屬性,並可返回變化後
的結果,那麼這里到底是值傳遞還是引用傳遞?
第三十一,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
第三十二,編程題: 寫一個Singleton出來。
以下是答案
第一,談談final, finally, finalize的區別。
final?修飾符(關鍵字)如果一個類被聲明為final,意味著它不能再派生出新的子類,不能作為父
類被繼承。因此一個類不能既被聲明為 abstract的,又被聲明為final的。將變數或方法聲明為final,
可以保證它們在使用中不被改變。被聲明為final的變數必須在聲明時給定初值,而在以後的引用中只能
讀取,不可修改。被聲明為final的方法也同樣只能使用,不能重載finally?再異常處理時提供 finally
塊來執行任何清除操作。如果拋出一個異常,那麼相匹配的 catch 子句就會執行,然後控制就會進入
finally 塊(如果有的話)。
finalize?方法名。Java 技術允許使用 finalize() 方法在垃圾收集器將對象從內存中清除出去
之前做必要的清理工作。這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的。它是
在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統資源或者執
行其他清理工作。finalize() 方法是在垃圾收集器刪除對象之前對這個對象調用的。
第二,Anonymous Inner Class (匿名內部類) 是否可以extends(繼承)其它類,是否可以
implements(實現)interface(介面)?
匿名的內部類是沒有名字的內部類。不能extends(繼承) 其它類,但一個內部類可以作為一個介面
,由另一個內部類實現。
第三,Static Nested Class 和 Inner Class的不同,說得越多越好(面試題有的很籠統)。
Nested Class (一般是C++的說法),Inner Class (一般是JAVA的說法)。Java內部類與C++嵌套
類最大的不同就在於是否有指向外部的引用上。具體可見http:
//www.frontfree.net/articles/services/view.asp?id=704&page=1
註: 靜態內部類(Inner Class)意味著1創建一個static內部類的對象,不需要一個外部類對象,2
不能從一個static內部類的一個對象訪問一個外部類對象
第四,&和&&的區別。
&是位運算符。&&是布爾邏輯運算符。
第五,HashMap和Hashtable的區別。
都屬於Map介面的類,實現了將惟一鍵映射到特定的值上。
HashMap 類沒有分類或者排序。它允許一個 null 鍵和多個 null 值。
Hashtable 類似於 HashMap,但是不允許 null 鍵和 null 值。它也比 HashMap 慢,因為它是同步
的。
第六,Collection 和 Collections的區別。
Collections是個java.util下的類,它包含有各種有關集合操作的靜態方法。
Collection是個java.util下的介面,它是各種集合結構的父介面。
第七,什麼時候用assert。
斷言是一個包含布爾表達式的語句,在執行這個語句時假定該表達式為 true。如果表達式計算為
false,那麼系統會報告一個 AssertionError。它用於調試目的:
assert(a > 0); // throws an AssertionError if a <= 0
斷言可以有兩種形式:
assert Expression1 ;
assert Expression1 : Expression2 ;
Expression1 應該總是產生一個布爾值。
Expression2 可以是得出一個值的任意表達式。這個值用於生成顯示更多調試信息的 String 消息。
斷言在默認情況下是禁用的。要在編譯時啟用斷言,需要使用 source 1.4 標記:
javac -source 1.4 Test.java
要在運行時啟用斷言,可使用 -enableassertions 或者 -ea 標記。
要在運行時選擇禁用斷言,可使用 -da 或者 -disableassertions 標記。
要系統類中啟用斷言,可使用 -esa 或者 -dsa 標記。還可以在包的基礎上啟用或者禁用斷言。
可以在預計正常情況下不會到達的任何位置上放置斷言。斷言可以用於驗證傳遞給私有方法的參數。
不過,斷言不應該用於驗證傳遞給公有方法的參數,因為不管是否啟用了斷言,公有方法都必須檢查其參
數。不過,既可以在公有方法中,也可以在非公有方法中利用斷言測試後置條件。另外,斷言不應該以任
何方式改變程序的狀態。
第八,GC是什麼? 為什麼要有GC? (基礎)。
GC是垃圾收集器。Java 程序員不用擔心內存管理,因為垃圾收集器會自動進行管理。要請求垃圾收
集,可以調用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()
第九,String s = new String("xyz");創建了幾個String Object?
兩個對象,一個是"xyx",一個是指向"xyx"的引用對象s。
第十,Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
Math.round(11.5)返回(long)12,Math.round(-11.5)返回(long)-11;
第十一,short s1 = 1; s1 = s1 + 1;有什麼錯? short s1 = 1; s1 += 1;有什麼錯?
short s1 = 1; s1 = s1 + 1;有錯,s1是short型,s1+1是int型,不能顯式轉化為short型。可修改為
s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正確。
第十二,sleep() 和 wait() 有什麼區別? 搞線程的最愛
sleep()方法是使線程停止一段時間的方法。在sleep 時間間隔期滿後,線程不一定立即恢復執行。
這是因為在那個時刻,其它線程可能正在運行而且沒有被調度為放棄執行,除非(a)"醒來"的線程具有更
高的優先順序,(b)正在運行的線程因為其它原因而阻塞。
wait()是線程交互時,如果線程對一個同步對象x 發出一個wait()調用,該線程會暫停執行,被調對
象進入等待狀態,直到被喚醒或等待時間到。
第十三,Java有沒有goto?
Goto?java中的保留字,現在沒有在java中使用。
第十四,數組有沒有length()這個方法? String有沒有length()這個方法?
數組沒有length()這個方法,有length的屬性。
String有有length()這個方法。
第十五,Overload和Override的區別。Overloaded的方法是否可以改變返回值的類型?
方法的重寫Overriding和重載Overloading是Java多態性的不同表現。重寫Overriding是父類與子類
之間多態性的一種表現,重載Overloading是一個類中多態性的一種表現。如果在子類中定義某方法與其
父類有相同的名稱和參數,我們說該方法被重寫 (Overriding)。子類的對象使用這個方法時,將調用子
類中的定義,對它而言,父類中的定義如同被"屏蔽"了。如果在一個類中定義了多個同名的方法,它們或
有不同的參數個數或有不同的參數類型,則稱為方法的重載(Overloading)。Overloaded的方法是可以改
變返回值的類型。
第十六,Set里的元素是不能重復的,那麼用什麼方法來區分重復與否呢? 是用==還是equals()? 它
們有何區別?
Set里的元素是不能重復的,那麼用iterator()方法來區分重復與否。equals()是判讀兩個Set是否相
等。
equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,為的是當兩個分離的對象的
內容和類型相配的話,返回真值。
第十七,給我一個你最常見到的runtime exception。
ArithmeticException, ArrayStoreException, BufferOverflowException,
BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException,
CMMException, , DOMException, EmptyStackException,
IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException,
IllegalStateException, ImagingOpException, IndexOutOfBoundsException,
MissingResourceException, NegativeArraySizeException, NoSuchElementException,
NullPointerException, ProfileDataException, ProviderException, RasterFormatException,
SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException,
UnsupportedOperationException
第十八,error和exception有什麼區別?
error 表示恢復不是不可能但很困難的情況下的一種嚴重問題。比如說內存溢出。不可能指望程序能
處理這樣的情況。
exception 表示一種設計或實現問題。也就是說,它表示如果程序運行正常,從不會發生的情況。
第十九,List, Set, Map是否繼承自Collection介面?
List,Set是
Map不是
第二十,abstract class和interface有什麼區別?
聲明方法的存在而不去實現它的類被叫做抽象類(abstract class),它用於要創建一個體現某些基
本行為的類,並為該類聲明方法,但不能在該類中實現該類的情況。不能創建abstract 類的實例。然而
可以創建一個變數,其類型是一個抽象類,並讓它指向具體子類的一個實例。不能有抽象構造函數或抽象
靜態方法。Abstract 類的子類為它們父類中的所有抽象方法提供實現,否則它們也是抽象類為。取而代
之,在子類中實現該方法。知道其行為的其它類可以在類中實現這些方法。
介面(interface)是抽象類的變體。在介面中,所有方法都是抽象的。多繼承性可通過實現這樣的
介面而獲得。介面中的所有方法都是抽象的,沒有一個有程序體。介面只可以定義static final成員變數
。介面的實現與子類相似,除了該實現類不能從介面定義中繼承行為。當類實現特殊介面時,它定義(即
將程序體給予)所有這種介面的方法。然後,它可以在實現了該介面的類的任何對象上調用介面的方法。
由於有抽象類,它允許使用介面名作為引用變數的類型。通常的動態聯編將生效。引用可以轉換到介面類
型或從介面類型轉換,instanceof 運算符可以用來決定某對象的類是否實現了介面。
第二十一,abstract的method是否可同時是static,是否可同時是native,是否可同時是
synchronized?
都不能
第二十二,介面是否可繼承介面? 抽象類是否可實現(implements)介面? 抽象類是否可繼承實體類
(concrete class)?
介面可以繼承介面。抽象類可以實現(implements)介面,抽象類是否可繼承實體類,但前提是實體類
必須有明確的構造函數。
第二十三,啟動一個線程是用run()還是start()?
啟動一個線程是調用start()方法,使線程所代表的虛擬處理機處於可運行狀態,這意味著它可以由
JVM調度並執行。這並不意味著線程就會立即運行。run()方法可以產生必須退出的標志來停止一個線程。
第二十四,構造器Constructor是否可被override?
構造器Constructor不能被繼承,因此不能重寫Overriding,但可以被重載Overloading。
第二十五,是否可以繼承String類?
String類是final類故不可以繼承。
第二十六,當一個線程進入一個對象的一個synchronized方法後,其它線程是否可進入此對象的其它
方法?
不能,一個對象的一個synchronized方法只能由一個線程訪問。
第二十七,try {}里有一個return語句,那麼緊跟在這個try後的finally {}里的code會不會被執行
,什麼時候被執行,在return前還是後?
會執行,在return前執行。
第二十八,編程題: 用最有效率的方法算出2乘以8等於幾?
有C背景的程序員特別喜歡問這種問題。
2 << 3
第二十九,兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?
不對,有相同的hash code。
第三十,當一個對象被當作參數傳遞到一個方法後,此方法可改變這個對象的屬性,並可返回變化後
的結果,那麼這里到底是值傳遞還是引用傳遞?
是值傳遞。Java 編程語言只由值傳遞參數。當一個對象實例作為一個參數被傳遞到方法中時,參數
的值就是對該對象的引用。對象的內容可以在被調用的方法中改變,但對象的引用是永遠不會改變的。
第三十一,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
switch(expr1)中,expr1是一個整數表達式。因此傳遞給 switch 和 case 語句的參數應該是 int
、 short、 char 或者 byte。long,string 都不能作用於swtich。
第三十二,編程題: 寫一個Singleton出來。
Singleton模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。
一般Singleton模式通常有幾種種形式:
第一種形式: 定義一個類,它的構造函數為private的,它有一個static的private的該類變數,
在類初始化時實例話,通過一個public的getInstance方法獲取對它的引用,繼而調用其中的方法。
public class Singleton {
private Singleton(){}
//在自己內部定義自己一個實例,是不是很奇怪?
//注意這是private 只供內部調用
private static Singleton instance = new Singleton();
//這里提供了一個供外部訪問本class的靜態方法,可以直接訪問
public static Singleton getInstance() {
return instance;
}
}
第二種形式:
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//這個方法比上面有所改進,不用每次都進行生成對象,只是第一次
//使用時生成實例,提高了效率!
if (instance==null)
instance=new Singleton();
return instance; }
}
其他形式:
定義一個類,它的構造函數為private的,所有方法為static的。
一般認為第一種形式要更加安全些
第三十三 Hashtable和HashMap
Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現
HashMap允許將null作為一個entry的key或者value,而Hashtable不允許
還有就是,HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因為
contains方法容易讓人引起誤解。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個線程訪問Hashtable時,
不需要自己為它的方法實現同步,而HashMap就必須為之提供外同步。
Hashtable和HashMap採用的hash/rehash演算法都大概一樣,所以性能不會有很大的差異。
C. c#面試問題及答案
c#面試問題及答案
c#面試問題及答案(一)
以下哪些可以作為介面成員?(多選) ( ABDE )
A.方法B.屬性C.欄位D.事件E.索引器
F.構造函數G.析構函數
.以下關於ref和out的描述哪些項是正確的?(多選) (ACD)
A.使用ref參數,傳遞到ref參數的參數必須最先初始化。
B.使用out參數,傳遞到out參數的參數必須最先初始化。
C.使用ref參數,必須將參數作為ref參數顯式傳遞到方法。
D.使用out參數,必須將參數作為out參數顯式傳遞到方法。
.“訪問范圍限定於此程序或那些由它所屬的類派生的類型”是對以下哪個成員可訪問性含義的正確描述?(B)
A.public B.protected C.internal D.protected internal
16.class Class1
{
private static int count = 0;
static Class1()
{
count++;
}
public Class1()
{
count++;
}
}
Class1 o1 = new Class1();
Class1 o2 = new Class1();
請問,o1.Count的值是多少?( C )
A.1 B.2 C.3 D.4
.abstract class BaseClass
{
public virtual void MethodA()
{
}
public virtual void MethodB()
{
}
}
class Class1: BaseClass
{
public void MethodA(string arg)
{
}
public override void MethodB()
{
}
}
class Class2: Class1
{
new public void MethodB()
{
}
}
class MainClass
{
public static void Main(string[] args)
{
Class2 o = new Class2();
Console.WriteLine(o.MethodA());
}
}
請問,o.MethodA調用的是: ( A )
A.BaseClass.MethodAB.Class2.MethodA
C.Class1.MethodAD.都不是
.請敘述屬性與索引器的區別。
屬性 索引器
通過名稱標識。 通過簽名標識。
通過簡單名稱或成員訪問來訪問。 通過元素訪問來訪問。
可以為靜態成員或實例成員。 必須為實例成員。
屬性的 get 訪問器沒有參數。 索引器的 get 訪問器具有與索引器相同的形參表。
屬性的 set 訪問器包含隱式 value 參數。 除了 value 參數外,索引器的 set 訪問器還具有與索引器相同的形參表。
請敘述const與readonly的區別。
每一個class至多隻可以定義一個static構造函數,並且不允許增加訪問級別關鍵字,參數列必須為空。
為了不違背編碼規則,通常把static數據成員聲明為private,然後通過statci property提供讀寫訪問。
const 關鍵字用於修改欄位或局部變數的聲明。它指定欄位或局部變數的值不能被修改。常數聲明引入給定類型的一個或多個常數。
const數據成員的聲明式必須包含初值,且初值必須是一個常量表達式。因為它是在編譯時就需要完全評估。
const成員可以使用另一個const成員來初始化,前提是兩者之間沒有循環依賴。
readonly在運行期評估賦值,使我們得以在確保“只讀訪問”的前提下,把object的初始化動作推遲到運行期進行。
readonly 關鍵字與 const 關鍵字不同:const 欄位只能在該欄位的聲明中初始化。readonly
欄位可以在聲明或構造函數中初始化。因此,根據所使用的構造函數,readonly 欄位可能具有不同的值。另外,const 欄位是編譯時常數,而 readonly
欄位可用於運行時常數。
readonly 只能在聲明時或者構造函數裡面初始化,並且不能在 static 修飾的構造函數裡面。
您需要創建一個ASP.NET應用程序,公司考慮使用Windows身份認證。
所有的用戶都存在於AllWin這個域中。您想要使用下列認證規則來配置這個應用程序:
a、匿名用戶不允許訪問這個應用程序。
b、所有雇員除了Tess和King都允許訪問這個應用程序。
請問您應該使用以下哪一個代碼段來配置這個應用程序?( A )
A. 〈authorization〉
〈deny users=”allwin ess, allwinking”〉
〈allow users=”*”〉
〈deny users=”?”〉
〈/authorization〉
B. 〈authorization〉
〈allow users=”*”〉
〈deny users=”allwin ess, allwinking”〉
〈deny users=”?”〉
〈/authorization〉
C. 〈authorization〉
〈deny users=”allwin ess, allwinking”〉
〈deny users=”?”〉
〈allow users=”*”〉
〈/authorization〉
D. 〈authorization〉
〈allow users=”allwin ess, allwinking”〉
〈allow users=”*”〉
〈/authorization〉
E.〈authorization〉
〈allow users=”*”〉
〈deny users=”allwin ess, allwinking”〉
〈/authorization〉
您要創建一個顯示公司員工列表的應用程序。您使用一個DataGrid控制項顯示員工的列表。您打算修改這個控制項以便在這個Grid的Footer顯示員工合計數。請問您應該怎麼做?(
C? )
A.重寫OnPreRender事件,當Grid的Footer行被創建時顯示合計數。
B.重寫OnItemCreated事件,當Grid的Footer行被創建時顯示合計數。
C.重寫OnItemDataBound事件,當Grid的Footer行被創建時顯示合計數。
D. 重寫OnLayout事件,當Grid的Footer行被創建時顯示合計數。
.您要創建ASP.NET應用程序用於運行AllWin公司內部的Web站點,這個應用程序包含了50個頁面。您想要配置這個應用程序以便當發生一個HTTP代碼錯誤時它可以顯示一個自定義的錯誤頁面給用戶。您想要花最小的代價完成這些目標,您應該怎麼做?(多選)(
CD )
A.在這個應用程序的Global.asax文件中創建一個Application_Error過程去處理ASP.NET代碼錯誤。
B.在這個應用程序的Web.config文件中創建一個applicationError節去處理ASP.NET代碼錯誤。
C.在這個應用程序的Global.asax文件中創建一個CustomErrors事件去處理HTTP錯誤。
D.在這個應用程序的Web.config文件中創建一個CustomErrors節去處理HTTP錯誤。
E.在這個應用程序的每一頁中添加一個Page指示符去處理ASP.NET 代碼錯誤。
F. 在這個應用程序的每一頁中添加一個Page指示符去處理ASP.NET HTTP錯誤。
您的公司有一個DB Server,名為AllWin,其上裝了MS SQLSERVER
2000。現在需要您寫一個資料庫連接字元串,用以連接AllWin上SQL
SERVER中的一個名為PubBase實例的Test庫。請問,應該選擇下面哪一個字元串?( B )
A.“Server=AllWin;Data Source=PubBase;Initial Catalog=Test;Integrated
Security=SSPI”
B.“Server= AllWin;Data Source=PubBase;Database=Test;Integrated Security=
SSPI”
C.“Data Source= AllWin PubBase;Initial Category=PubBase;Integrated
Security= SSPI”
D.“Data Source= AllWin PubBase;Database=Test;Integrated Security=
SSPI”
您為AllWin公司創建了一個ASP.NET應用程序。這個應用程序調用一個 Xml Web Service。這個 Xml Web Service
將返回一個包含了公司雇員列表的DataSet對象。請問您該如何在這個程序中使用這個 Xml Web Service?( ? )
A.在“引用”對話框的'.Net標簽中選擇 System.Web.Services.dll。
B.在“Web引用”對話框中輸入這個 XML Web service 的地址。
C.在您的 Global.asax.cs 中添加一條 using 語句並指定這個 XML Web service 的地址。
D.在您的 Global.asax.cs 中寫一個事件處理器導入這個 Xml Web Service 相應的 .wsdl 和 .disco
文件。
.您要創建一個ASP.NET應用程序在DataGrid控制項中顯示一個經過排序的列表。產品數據被存放於一個名為PubBase的Microsoft
SQL Server
資料庫。每個產品的主鍵是ProctID,Numeric型並且每個產品有一個字母描述欄位,名為ProctName。您使用一個SqlDataAdapter對象和一個SqlCommand對象通過調用一個存儲過程從資料庫中獲取產品數據。您將SqlCommand對象的CommandType屬性設置為CommandType.StoredProcere,並將它的CommandText屬性設置為procProctList。您成功的獲取了一個DataTable對象,其中是已經按ProctID降序排列的產品列表。您打算顯示以相反的字母順序排列的ProctName,請問該怎麼做?
( B )
A. 將SqlCommand對象的CommandType屬性修改為CommandType.Text,將CommandText屬性修改為”SELECT
* FROM procProctList ORDER BY ProctName
DESC”。然後將這個DataTable對象綁定到DataGrid控制項。
B. 創建一個基於這個DataTable對象的新的DataView並將這個DataView的Sort屬性設置為“ProctName
DESC”。然後將這個DataView對象綁定到DataGrid控制項。
C. 將DataGrid控制項的AllowSorting屬性設置為True,並將DataGridColumn的SortExpression屬性設置為
“ProctName DESC”.以顯示ProctName。然後將這個DataTable對象綁定到DataGrid控制項。
D. 將DataTable對象的DisplayExpression屬性設置為 “ORDER BY ProctName
DESC”.。然後將這個DataTable對象綁定到DataGrid控制項。
.C#代碼實現,確保windows程序只有一個實例(instance)
///〈summary〉
///應用程序的主入口點。
///〈/summary〉
[STAThread]
staticvoid Main()
{
//防止程序多次運行
if(!OneInstance.IsFirst(“GetPayInfo“))
{
MessageBox.Show (“警告:程序正在運行中!
請不要重復打開程序!可在右下角系統欄找到!“,“程序錯誤提示:“,MessageBoxButtons.OK,MessageBoxIcon.Stop);
return;
}
Application.Run(new Form1());
}
// ******************* 防止程序多次執行 **************************
publicabstractclass OneInstance
{
///〈summary〉
///判斷程序是否正在運行
///〈/summary〉
///〈param name=“appId“〉程序名稱〈/param〉
///〈returns〉如果程序是第一次運行返回True,否則返回False〈/returns〉
publicstaticbool IsFirst(string appId)
{
bool ret=false;
if(OpenMutex(0x1F0001,0,appId)==IntPtr.Zero)
{
CreateMutex(IntPtr.Zero,0,appId);
ret=true;
}
return ret;
}
[DllImport(“Kernel32.dll“,CharSet=CharSet.Auto)]
privatestaticextern IntPtr OpenMutex(
uint dwDesiredAccess, // access
int bInheritHandle, // inheritance option
string lpName // object name
);
[DllImport(“Kernel32.dll“,CharSet=CharSet.Auto)]
privatestaticextern IntPtr CreateMutex(
IntPtr lpMutexAttributes, // SD
int bInitialOwner, // initial owner
string lpName // object name
);
}
簡述 private、protected、public、internal 修飾符的訪問許可權。
private : 私有成員, 在類的內部才可以訪問。protected : 保護成員,該類內部和繼承類中可以訪問。public :
公共成員,完全公開,沒有訪問限制。internal: 在同一命名空間內可以訪問。
寫出一條Sql語句: 取出表A中第31到第40記錄(SQLServer, 以自動增長的ID作為主鍵, 注意:ID可能不是連續的。)
select top 10 * from A where id not in (select top 30 id from A)
解2: select top 10 * from A where id 〉 (select max(id) from (select top 30
id from A )as A)
c#面試問題及答案(二)
1, 請你說說.NET中類和結構的區別?
答:結構和類具有大體的語法,但是結構受到的限制比類要多。結構不能申明有默認的構造函數,為結構的副本是又編譯器創建和銷毀的,所以不需要默認的構造函數和析構函數。結構是值類型,所以對結構變數所做的改變不會影響其的原值,而類是應用類型,改變其變數的值會改變其原值。申明結構用Struck關鍵字,申明類用class關鍵字,向方法傳遞結構是時是通過值傳遞的,而不是通過引用。與類不同,結構的實例化可以不使用New關鍵字。類可以實現介面。
2, 死鎖的必要條件?怎麼克服?
答:系統的資源不足,進程的推進的順序不合適,資源分配不當,一個資源每次只能被一個進程使用,一個資源請求資源時,而此時這個資源已阻塞,對已獲得資源不放,進程獲得資源時,未使用完前,不能強行剝奪。
3, 介面是否可以繼承介面?抽象類是否可以實現介面?抽象類是否可以繼承實體類?
答:介面是可以繼承介面的,抽象類是可以實現介面的,抽象類可以繼承實體類,但是有個條件,條件是,實體類必須要有明確的構造函數。
4, 構造器Constructor是否可以被繼承?是否可以被Override?
答:Constructor不可以被繼承,因此不能被重寫(Overriding),但可以被重載(Overloading).
5, 當一個線程進入一個對象的方法後,其它線程是否可以進入該對象的方法?
答:不可以,一個對象的方法只能由一個線程訪問。
6, 用最有效的方法算出等已8對於幾?
答:2<<3.
7, C#是否可以對內存直接進行操作?
答:這個問題比較難回答,也是個很大的問題。但是可以這樣問答。C#是可以對內存進行直接操作的,雖然很少用到指針,但是C#是可以使用指針的,在用的時候需要在前邊加unsafe,,在.net中使用了垃圾回收機制(GC)功能,它替代了程序員,不過在C#中不可以直接使用finalize方法,而是在析構函數中調用基類的finalize()方法。
8, Error和Exception有是區別?
答:error表示恢復不是不可能,但是很困難,exception表示一種實際或實現問題,它表示程序運行正常不可以發生的。
9, 談談final,finally,finallize的區別?
答:final用於申明屬性,方法和類,表示屬性不可變,方法不可以被覆蓋,類不可以被繼承。
Finally是異常處理語句結構中,表示總是執行的部分。
Finallize表示是object類一個方法,在垃圾回收機制中執行的時候會被調用被回收對象的方法。
10, HashMap和Hashtable區別?
答:HashMap是Hashtable的輕量級實現,非線程安全的實現他們都實現了map介面,主要區別是HashMap鍵值可以為空null,效率可以高於Hashtable。
11,Collection和Collections的區別?
答:Collection是集合類的上級介面,Collections是針對集合類的一個幫助類,它提供一系列靜態方法來實現對各種集合的搜索,排序,線程安全化操作。
12,C#中委託是什麼?事件是不是一種委託?
答:委託是一種安全的類似與函數指針,但是她比指針要安全的多,它可以把方法作為一個參數傳遞給另一個方法,可以理解為指向函數的引用。事件是一種消息機制,它是一種委託,委託不帶方法體。
13,Override, Overload,的區別?
答:Override是重寫的意思,它表示重寫基類的方法,而且方法的名稱,返回類型,參數類型,參數個數要與基類相同。
Overload是重載是意思,它也表示重寫基類的方法,但是只要方法名相同,別的可以不同。
14,在一個BS結構中需要傳遞變數值時,不能使用session,coolke,application,你有幾中方法?
答:this.server.Transfer,Querystring.
15, C#種索引器實現過程,是否只能根據數字索引?
答:不是的,可以是任意類型。
16,New有種用法?
答:有3種,第一種是,實例化如:New Class()
第二種是,public new 隱藏基類的方法
第三種是,在泛型類申明中的任何類型參數都必須有公共的無參構造函數。
17,任何把一個Array復制到Arraylist中?
答:Foreach (object o in Array), ArrayList.Add (0)
等有好多中種方法。自己想。
18,概述反射和序列化?
答:反射:要給發射下一個定義還是比較難的,這里先說說我的理解。反射提供了封裝程序集,模塊和類型對象,可以用反射動態地創建類型的實例,將類型綁定到現有對象,或者從現有對象類型里獲取類型,然後調用類型的方法或訪問欄位和屬性。
序列化:將對象轉換為另一種媒介傳輸的格式過程。如,序列化一個對象,用Http通過internet在客戶端和伺服器之間傳遞該對象,在另一端用反序列化從該流中重新得到對象。
19,Const和ReadOnly?
答:Const用來申明編程時申明常量,ReadOnly用來申明運行時常量。
20,UDP和TCP連接有和異同?
答:TCP是傳輸控制協議,提供的是面向連接的,是可靠的,位元組流服務,當用戶和伺服器彼此進行數據交互的時候,必須在他們數據交互前要進行TCP連接之後才能傳輸數據。TCP提供超時重撥,檢驗數據功能。UDP是用戶數據報協議,是一個簡單的面向數據報的傳輸協議,是不可靠的連接。
21,進程和線程分別該怎麼理解?
答:進程是比線程大的程序運行單元,都是由操作系統所體會的系統運行單元,一個程序中至少要有一個進程,有一個進程中,至少要有一個線程,線程的劃分尺度要比進程要小,進程擁有獨立的內存單元,線程是共享內存,從而極大的提高了程序的運行效率同一個進程中的多個線程可以並發執行。
22,ASP.NET頁面之間傳遞值的幾種方式?
答:QueryString,session,cookies,application,server.Transfer,respose.redictor.
23. 什麼叫應用程序域?什麼是託管代碼?什麼是強類型系統?什麼是裝箱和拆箱?什麼是重載?CTS、CLS和CLR分別作何解釋?
答:應用程序域:就是為安全性,可靠性,隔離性,和版本控制,及卸載程序提供的隔離邊界。它通常由運行庫宿主創建,應用程序域提供了一個更安全,用途更廣的處理單元。
託管代碼:使用CLR編譯語言編輯器開發編寫的代碼就叫託管代碼。
裝箱和拆箱:是把值類型轉換為引用類型的過程,是隱式的,相反的過程就是拆箱,是顯式的。
CTS是公共類型系統,CLS是公共語言規范,CLR公共語言運行庫。
強類型系統:每個變數和對象都必須具有申明類型。
24. 值類型和引用類型的區別?
答:值類型的值是存放在堆棧中的,改變其值,不改變變數原有的值,而引用類型的值是存放在棧中的,其引用的地址是存放在堆棧中的,改變其值也就改變了變數原有的值。值類型不允許包含null值,然而可空類型可以將null賦值給值類型l。
25. ASP.net的身份驗證方式有哪些?
答:windows,forms,passport
26. 解釋一下UDDI、WSDL的意義及其作用?
答:UDDI是統一描述集成協議,是一套基於Web的,分布式的,為WEB服務提供的信息注冊的實現標准規范,同時為也是為企業本身提供的Web服務注冊以讓別的企業能夠發現並訪問的協議標准。提供了基於標準的規范,用於描述和發現服務,還提供了一組基於網際網路的實現。
WSDL這是一個基於XML的描述WEB服務的介面。
27. 什麼是SOAP?
答:是簡單訪問協議。是在分布式環境中,交換信息並實現遠程調用的協議。是一個基於XML的協議。使用SOAP,可以不考慮任何傳輸協議,但通常還是HTTP協議,可以允許任何類型的對象或代碼,在任何平台上,以任一種語言相互通信。它是一種輕量級協議。
28. 如何部署一個ASP.net頁面?
答:vs2003,vs2005里邊都有發表機制,vs2003可以發布然後在復制部署。
Vs2005可以直接部署到對應的位置。
29. 如何理解.net中的垃圾回收機制?
答:.NET中的垃圾回收機制是引用程序對內存的回收和釋放。當每次用new關鍵字創建一個對象時,運行庫都要從託管堆中為其分配內存,因為空間是有限的,最終垃圾回收機制是要回收不用的內存的。已釋放內存,重新使用。
30. 面向對象的三大基本原則?
答:封裝,繼承,多態。
;D. 程序員人品面試題及答案,HR必備!
在我們招聘技術的時候,如果只是一個面試官面試,通常會遇到,面試管徇私舞弊,類似狗眼看人低,或者遇到高手心存嫉妒不願招聘此人的情況,從而剔除掉面試的人才,無法有效招聘到公司所需的人。
如何避免面試人員的徇私舞弊,就至關重要,我們統長可以通過加試的流程,或者加面的流程來規避這種事情,通常情況下,我們也可以通過筆試+面試+面試2的流程進行,這樣的環節越多,面試官徇私舞弊的問題就越少,對於重要的崗位我們依然要綜合考慮清晰,不能讓人品差的人混入。
1.排擠或者拉幫結派,在公司內部製造不和睦的情景。
2.影響公司的正常運營,還可能存在貪污腐敗像閑。
3.可以吃回扣的崗位,尤其是采購會給公司造成重大的損失。
對此我總結和個人的經驗,整理如下的10個人品測試題,每小題10分共100分,同樣的您可以和技術題混合在一起對求職者進行這樣的筆試。
如果A是您的直屬領導,當遇到了緊急情況,且你正在忙手頭要緊事,需要你的協助或者幫助時你會怎麼做?( )
A.盡力而為 B.手上工作忙,會建議找別人 C.我沒有必要幫助他人 D.放下手頭要緊的事,去協助領導
答案:B
解析:作為領導,和下屬都屬於公司員工,沒有誰更加需要幫助,只有自己的工作職責,和同事之間的互幫互助行為,二遇到這種事,應是優先做好的自己的事,再去幫助他人,選A的人是屬於,阿諛奉承拍馬屁的類型,選C的人是極度理性,且規規矩矩的人,選D的人是屬於,斜度個人工作職責的行為。
如果A是您的直屬領導,他今天搬家,告訴你去他家裡幫忙,他這種行為屬於?( )
A.徇私舞弊 B.私事公辦 C.小氣 D.欺負員工
答案:B
解析:作為領導,搬家時個人私事,不能要求任何的員工幫忙,且給錢也不行,這種行為屬於私事公辦。
直屬的領導,再一次工作失誤後,果斷甩鍋下屬,且指責有續,領導的這種行為是否屬於正常范疇,遇到這種的事情,領導最好應該怎麼做?
簡答題:兩問,行為和怎麼做。
在公共場所,因為瑣事辱罵他人或者領導,這種行為屬於什麼行為,是否違法,能否維權?
簡答題:三問,行為、違法和如何維權,主要考的求職者對法律和道德的認知。
當你下班途中,遇到一個摔倒的老人,這附近有很多碰瓷的傳聞,且沒有攝像頭和路人,這時候你會怎麼做?
A.默默路過,並報警。 B.先報警,然後扶起老人 C.錄視頻,且報警,扶起老人 D.回去叫人
答案:C
解析:只有C是最好的處理方式,且能體現出這位求職者的心思縝密。
如果以後你面試新人,遇到一個能力特別強的人,但沒有學歷,且人說話很沖,工作能力完全過關,你會向領導反應錄取他嘛?()
A.不會,沒學歷 B.可能對我有影響,拒絕錄用 C.繼續等待其他合適人選 D.和領導與同事商議後錄用
答案:D
解析:
選A的人可以看出這不是一個好的員工。公司是一個商業組織,目的是為了盈利,能力強的人往往求之不得,不能因為學歷問題剔除。
選B的人可以看出這是一個小氣,且人品和眼界都很低的員工,建議直接pass,後續對公司的發展也不好。
選C的人可以看出是個負責任的員工,會選擇繼續等待更合適的人選。
在你身上發生了一件事,並不是丑聞,也不是壞事,就是一件很平常的事情,這時你會覺得?()
A.自己是焦點 B.不想去上班 C.自己丟人了 D.散布的這個人真可惡 E.平平淡淡
答案:E
解析:有心理疾病的人,才會覺得自己是焦點,才會有負面情緒。
如果你是個技術大牛,且領導要求你必須教導其他人,你會怎麼做?()
A.熱心是不需要強迫的,會不代表一定要交
B.不聽從領導的話
C.要求公司給予,教導他人的費用。
D.接受領導的要求去教人。
答案:C
解析:技術是自己的,屬於個人,不屬於公司,且教不教不需要強制,強制屬於違法行為,懂得不代表義務教導,這屬於行為綁架的行為。
領導一直強制你做事,且必須你做,出了事就甩鍋給你,你會怎麼做?()
A.辭職不幹 B.向更高領導舉報 C.果斷拒絕 D.頂撞領導
答案:B A
解析:有這樣愛甩鍋的公司領導,也不是什麼好公司,在這里工作不是勾心鬥角就是你爭我奪,故此B和A都是對的。
假如你遇到困難,你不想得到別人的幫助,但是就是有人要幫你,這種行為屬於什麼行為?()
A.強人所難 B.太過熱心 C.不考慮其他人感受 D.不尊重我的主觀意圖
答案:A B C D
解析:這是多選題,都對,別人不需要那麼就應該尊重別人,即使是送黃金,也會有人不需要的時候,不需要而自以為是強迫別人接受,就屬於強人所難,不考慮其他人感受,不尊重個人主觀意圖。
E. C語言筆試或面試一般會問到什麼問題
既然是面試,一定要提前准備,最好准備一套自我介紹,包括對IT行業的看法之類,面試官經常會問這些問題。
由於c語言是程序員工作語種的其中1個,所以對於程序員這個工種,還是有一些具體的注意事項:
第一、基礎很重要,不要生疏了。
不管應聘什麼開發崗位,基礎永遠是最重要的。IT業不停地在炒作新概念,昨天是SOA,今天是雲計算。我們永遠不知道明天流行什麼,但是只要有踏實的基礎,輔以較好的學習能力,要跟上步伐也不會太難。所以絕大多數公司都會特別看重應聘人員的基礎能力,比如編程語言本身的特性、基本的演算法和數據結構、進程間通信等等,畢竟這些具體技術問題有客觀的答案,而且在各具體行業都是相通的。
工作三年以上的人,往往都習慣了「拷貝+修改」式的工作,用不到的基礎知識基本上都忘掉了,一到應聘的時候就難免眼高手低,總是抓不住機會。
而事實上,技術基礎即便是遺忘了,也是可以很快撿起來的。如果求職者確實忘了很多基礎知識,那麼參加面試的前夜,花點時間把大學里的課本再翻出來看看吧。似乎很土的方法,但確實是有效的。
第二、要關注技術前沿。
不管做任何工作,如果只顧著低頭做事,而不曉得抬頭看天。那麼不管做多久,自身的水平總是停留在畢業時的水平;如果基礎又忘記了太多,那還不如畢業生。
關注技術前沿,並不是要求跟進每一個新技術,而只需關注目前主流媒體經常宣傳的一些新技術、新思想。關注這些技術前沿的動向,並能與自己從事的工作聯系起來作一些深入思考,那麼這是向面試官宣揚求職者的學習能力的一種好辦法。
第三、小公司比較看重知識的廣度,大公司更看重知識的深度。
如果求職業想去一些小公司工作,那麼由於他們人少,分工沒那麼細,所以用人單位大多喜歡知識面廣的應聘者——求職者會聽到更多的「怎麼做」。對於應聘這樣的公司,求職者可以著重培養知識的廣度,比如做網站後台開發,最好也能js、css、apache、mysql都懂一些,能獨自搭建一套完整的網站,這樣去很多小公司難度都不太大。但是由於個人的精力總是有限的,所以要注意不要鋪得太開,重點還是在後台開發本身。
而大公司由於分工比較明細,所以往往更喜歡考量重點知識面的深度——求職者會聽到更多的「為什麼」。所以平常解決問題時,不要光搜索一把解決了就完了,還需要仔細研究各種問題的來龍去脈,並能分析總結,將這些收獲系統化、理論化。
當然,廣度和深度的需求不是絕對的,一個優秀的開發人員應該對至少一到兩個專業領域有著深入的了解,並熟悉其他相關領域,也就是所謂的一專多能。
第四、良好的簡歷設計可以為你的應聘加分。
社會應聘的簡歷往往比校園應聘的簡歷寫得隨意,因為有工作經驗的人往往認為面試官會更看重他的工作經驗,而不是簡歷格式。其實不然。
大多數簡歷只會出現在面試官面前10秒到1分鍾不等。這個短短的時間內,如何讓求職者脫穎而出?這個方面有很多的攻略,我只說重點建議,不解釋原因。
一是簡歷要突出優勢,而不是描述經歷。比如出身名校、就職過名企、參與過著名項目、拿過大獎,這些比較客觀的優勢要重點突出。如果求職者沒有UI的功底,那麼簡單地放大加粗也可以達到效果。當然有些公司只接受文本型簡歷,那就設法加一些特殊符號吧。
二是技術簡歷減少模糊化的語句,最好能數字化。例如項目代碼量,維護的數據量,網站的訪問量,請求平均耗時等等。
三是簡歷要能結合應聘崗位做一些匹配的修改。撇開招聘網站通用的簡歷不談,如果求職者明確對一個特定公司的特定崗位投出簡歷,那麼求職者有必要把跟對應崗位無關的內容弱化,並強化跟其業務相關的內容。如果實在行業差別太大,那麼表達幾句對其行業的見解和興趣也是可以的。
第五、要有積極的溝通意識。
優秀的面試官會激勵應聘者講他原先工作的內容,並從而評估出應聘者的能力水平。但隔行如隔山,絕大多數面試官會慢慢將問題引向自己熟悉的領域——這往往又是應聘者不太熟悉的領域。這就要求應聘者能積極分析面試官的興趣點,並將自己相近的特長表現出來。
如果跟面試官有了意見沖突,也盡量不要再同一個問題上糾纏。那也許是故意製造的陷阱——看看求職者的團隊意識。應聘者需要明白的是,在面試場合中不要妄圖「戰勝」面試官,即便是碰上一個期望「戰勝」應聘者的面試官。
第六、要有良好的表達能力。
沒有哪個面試官喜歡啰啰嗦嗦說了半天還是沒說到點子上的應聘者,所以要盡量簡明扼要地回答問題,除非面試官確實表現出對具體細節的興趣。 回答問題時注意麵試官的情緒變化,一旦他表現出任何想打斷的意願,立即一句話結束這個話題。有些比較復雜的問題,可以先思考十到二十秒鍾,因為一旦開口就沒有思考的時間,話多的人不容易收住話題。
跟學校考試不一樣,大多數主觀性問題並不要求應聘者一二三四說得滴水不漏,能說到大部分關鍵點就是可以的了。另外注意,各種技術術語不要搞混了。搞不清楚的理論概念,不如不說。免得面試官聽到個術語就拉出來窮追猛打,把自己問掛。
第七、自信。
大多數做技術的,平時都信心滿滿,一到應聘的時候卻總覺得自己不懂的東西還太多。回答問題時聲音太小,或者畏畏縮縮用很多「可能」「也許」「大概」。這個不一定影響求職者的錄用,但是不自信的表現無疑會影響在跟HR談薪水時候的議價能力。所以,無論如何,應聘的時候表現得輕松鎮定一些,還是很有好處的。
當然,自信和自大之間往往只有一線之差。千萬小心,不要過度地表現自信搞成了自大,因為HR往往對這一點非常敏感。如果求職者只是要謹慎地表現自信的話,只要回答問題時面帶微笑就夠了。
最後需要特別提醒的是,以上種種其實只不過是應聘時的技巧和注意點而已。職業規劃需要有長遠的眼光和堅持不懈的學習。台上一分鍾,台下十年功。真正的實力還是要在平時工作和學習中進行積累。
F. 面試C++ 程序員,什麼樣的問題是好問題
作者:陳碩
鏈接:http://www.hu.com/question/20184857/answer/24537006
來源:知乎
著作權歸作者所有,轉載請聯系作者獲得授權。
對於應屆生:
標准庫各容器的基本操作的復雜度。標准庫演算法的復雜度,例如 std::sort() 的平均復雜度、最壞復雜度(答 O(N^2) 和 O(N log N) 都算對),最壞情況什麼時候出現。
標准庫各容器(deque 除外)的數據結構(標准黨勿噴,主流 STL 實現的數據結構都差不多),以及 vector 的容量增長方式。如果回答得特別好,還可以補充問為什麼 vector::push_back() 的復雜度是分攤之後的 O(1),作為加分。
出一道使用 lower_bound / upper_bound 能輕松解決的簡單演算法題;或者實現 set_intersection() 或 set_union() 或 merge();或者實現 word count,統計每個單詞出現的次數(最多十幾行代碼),如果有時間,輸出時再按出現次數排序。
對於社招,補充問:
迭代器失效。(不要求記住所有的場景,但要有這個概念,其實知道數據結構的話不難推理。)
標准庫的線程安全性。
自動化對象生命期管理,智能指針,循環引用,weak_ptr。
list 的 insert()/erase() 與 vector 相比哪個快。(這個不是那麼簡單。)
關於什麼是好的面試題,多說幾句我的看法:
面試官向誰負責。通常應聘者會面試幾輪,收集多個面試官的 feedback,交給 hire manager 或 hire committee 決定是否錄用。也就是說面試官無權單獨決定是否錄用這個候選人。在此前提下,面試官的任務是收集足夠多的有效信息(包括面試題、答案、答題過程等等),供 hire manager 或 hire committee 決斷。因此,面試題要有說服力。應聘者答上了這道面試題,能說明什麼,如果沒答上來,又能說明什麼。不符合這一要求的不是好題目。
難度與區分度。難度定位在「一個合格的 C++ 程序員應該掌握的基本知識」,是招能用 C++ 幹活的人,不是招標准控或語言律師。所有人都能做出來和所有人都做不出來的題目,沒有區分度,不是好題目。所有應聘者都能通過或者所有應聘者都被刷掉的面試官也不是好面試官。
公平性與可重復性。技術面試題應該有比較公認的正確答案,怎麼樣算答得好,不僅由面試官一個人做出判斷,hire manager 和 hire committee 也能重復這一判斷。一套好題目,能起到篩選多個面試者的作用,比如「眼前這個應聘者的回答與過去六個月里的應聘者相比,處於前 10 % 的位置」,這就是不錯的客觀標桿。
G. 嵌入式開發—C語言面試題
嵌入式開發—C語言面試題
隨著醫療電子、智能家居、物流管理和電力控制等方面的不斷風靡,嵌入式系統利用自身積累的底蘊經驗,重視和把握這個機會,想辦法在已經成熟的平台和產品基礎上與應用感測單元的結合,擴展物聯和感知的支持能力,發掘某種領域物聯網應用。下面是關於嵌入式開發—C語言面試題,希望大家認真閱讀!
1. 用預處理指令#define 聲明一個常數,用以表明1年中有多少秒(忽略閏年問題)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
我在這想看到幾件事情:
1). #define 語法的基本知識(例如:不能以分號結束,括弧的使用,等等)
2). 懂得預處理器將為你計算常數表達式的值,因此,直接寫出你是如何計算一年中有多少秒而不是計算出實際的值,是更清晰而沒有代價的。
3). 意識到這個表達式將使一個16位機的整型數溢出-因此要用到長整型符號L,告訴編譯器這個常數是的長整型數。
4). 如果你在你的表達式中用到UL(表示無符號長整型),那麼你有了一個好的起點。記住,第一印象很重要。
2. 寫一個“標准”宏MIN,這個宏輸入兩個參數並返回較小的一個。
#define MIN(A,B) ((A) <= (B) (A) : ))
這個測試是為下面的目的而設的:
1). 標識#define在宏中應用的基本知識。這是很重要的,因為直到嵌入(inline)操作符變為標准C的一部分,宏是方便產生嵌入代碼的唯一方法,對於嵌入式系統來說,為了能達到要求的性能,嵌入代碼經常是必須的方法。
2). 三重條件操作符的知識。這個操作符存在C語言中的原因是它使得編譯器能產生比if-then-else更優化的代碼,了解這個用法是很重要的。
3). 懂得在宏中小心地把參數用括弧括起來
4). 我也用這個問題開始討論宏的副作用,例如:當你寫下面的代碼時會發生什麼事?
least = MIN(*p++, b);
3. 預處理器標識#error的目的是什麼?
如果你不知道答案,請看參考文獻1。這問題對區分一個正常的伙計和一個書獃子是很有用的。只有書獃子才會讀C語言課本的附錄去找出象這種
問題的答案。當然如果你不是在找一個書獃子,那麼應試者最好希望自己不要知道答案。
死循環(Infinite loops)
4. 嵌入式系統中經常要用到無限循環,你怎麼樣用C編寫死循環呢?
這個問題用幾個解決方案。我首選的方案是:
while(1) { }
一些程序員更喜歡如下方案:
for(;;) { }
這個實現方式讓我為難,因為這個語法沒有確切表達到底怎麼回事。如果一個應試者給出這個作為方案,我將用這個作為一個機會去探究他們這樣做的
基本原理。如果他們的基本答案是:“我被教著這樣做,但從沒有想到過為什麼。”這會給我留下一個壞印象。
第三個方案是用 goto
Loop:
...
goto Loop;
應試者如給出上面的方案,這說明或者他是一個匯編語言程序員(這也許是好事)或者他是一個想進入新領域的BASIC/FORTRAN程序員。
數據聲明(Data declarations)
5. 用變數a給出下面的定義
a) 一個整型數(An integer)
b) 一個指向整型數的指針(A pointer to an integer)
c) 一個指向指針的的指針,它指向的指針是指向一個整型數(A pointer to a pointer to an integer)
d) 一個有10個整型數的數組(An array of 10 integers)
e) 一個有10個指針的數組,該指針是指向一個整型數的(An array of 10 pointers to integers)
f) 一個指向有10個整型數數組的指針(A pointer to an array of 10 integers)
g) 一個指向函數的指針,該函數有一個整型參數並返回一個整型數(A pointer to a function that takes an integer as an argument and returns an integer)
h) 一個有10個指針的數組,該指針指向一個函數,該函數有一個整型參數並返回一個整型數( An array of ten pointers to functions that take an integer argument and return an integer )
答案是:
a) int a; // An integer
b) int *a; // A pointer to an integer
c) int **a; // A pointer to a pointer to an integer
d) int a[10]; // An array of 10 integers
e) int *a[10]; // An array of 10 pointers to integers
f) int (*a)[10]; // A pointer to an array of 10 integers
g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer
人們經常聲稱這里有幾個問題是那種要翻一下書才能回答的問題,我同意這種說法。當我寫這篇文章時,為了確定語法的正確性,我的確查了一下書。
但是當我被面試的時候,我期望被問到這個問題(或者相近的問題)。因為在被面試的這段時間里,我確定我知道這個問題的答案。應試者如果不知道
所有的答案(或至少大部分答案),那麼也就沒有為這次面試做准備,如果該面試者沒有為這次面試做准備,那麼他又能為什麼出准備呢?
Static
6. 關鍵字static的作用是什麼?
這個簡單的問題很少有人能回答完全。在C語言中,關鍵字static有三個明顯的作用:
1). 在函數體,一個被聲明為靜態的變數在這一函數被調用過程中維持其值不變。
2). 在模塊內(但在函數體外),一個被聲明為靜態的變數可以被模塊內所用函數訪問,但不能被模塊外其它函數訪問。它是一個本地的全局變數。
3). 在模塊內,一個被聲明為靜態的函數只可被這一模塊內的其它函數調用。那就是,這個函數被限制在聲明它的模塊的本地范圍內使用。
大多數應試者能正確回答第一部分,一部分能正確回答第二部分,同是很少的人能懂得第三部分。這是一個應試者的嚴重的缺點,因為他顯然不懂得本地化數據和代碼范圍的好處和重要性。
Const
7.關鍵字const是什麼含意?
我只要一聽到被面試者說:“const意味著常數”,我就知道我正在和一個業余者打交道。去年Dan Saks已經在他的文章里完全概括了const的所有用法,因此ESP(譯者:Embedded Systems Programming)的每一位讀者應該非常熟悉const能做什麼和不能做什麼.
如果你從沒有讀到那篇文章,只要能說出const意味著“只讀”就可以了。盡管這個答案不是完全的答案,但我接受它作為一個正確的答案。(如果你想知道更詳細的答案,仔細讀一下Saks的文章吧。)如果應試者能正確回答這個問題,我將問他一個附加的問題:下面的聲明都是什麼意思?
const int a;
int const a;
const int *a;
int * const a;
int const * a const;
前兩個的作用是一樣,a是一個常整型數。第三個意味著a是一個指向常整型數的指針(也就是,整型數是不可修改的,但指針可以)。第四個意思a是一個指向整型數的常指針(也就是說,指針指向的整型數是可以修改的,但指針是不可修改的)。最後一個意味著a是一個指向常整型數的常指針(也就是說,指針指向的整型數是不可修改的,同時指針也是不可修改的)。如果應試者能正確回答這些問題,那麼他就給我留下了一個好印象。順帶提一句,也許你可能會問,即使不用關鍵字 const,也還是能很容易寫出功能正確的程序,那麼我為什麼還要如此看重關鍵字const呢?我也如下的幾下理由:
1). 關鍵字const的作用是為給讀你代碼的人傳達非常有用的信息,實際上,聲明一個參數為常量是為了告訴了用戶這個參數的應用目的。如果你曾花很多時間清理其它人留下的垃圾,你就會很快學會感謝這點多餘的信息。(當然,懂得用const的程序員很少會留下的垃圾讓別人來清理的。)
2). 通過給優化器一些附加的信息,使用關鍵字const也許能產生更緊湊的代碼。
3). 合理地使用關鍵字const可以使編譯器很自然地保護那些不希望被改變的參數,防止其被無意的代碼修改。簡而言之,這樣可以減少bug的出現。
Volatile
8. 關鍵字volatile有什麼含意 並給出三個不同的例子。
一個定義為volatile的變數是說這變數可能會被意想不到地改變,這樣,編譯器就不會去假設這個變數的值了。精確地說就是,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用保存在寄存器里的備份。下面是volatile變數的幾個例子:
1). 並行設備的硬體寄存器(如:狀態寄存器)
2). 一個中斷服務子程序中會訪問到的非自動變數(Non-automatic variables)
3). 多線程應用中被幾個任務共享的變數
回答不出這個問題的人是不會被僱傭的。我認為這是區分C程序員和嵌入式系統程序員的最基本的問題。嵌入式系統程序員經常同硬體、中斷、RTOS等等打交道,所用這些都要求volatile變數。不懂得volatile內容將會帶來災難。
假設被面試者正確地回答了這是問題(嗯,懷疑這否會是這樣),我將稍微深究一下,看一下這傢伙是不是直正懂得volatile完全的重要性。
1). 一個參數既可以是const還可以是volatile嗎?解釋為什麼。
2). 一個指針可以是volatile 嗎?解釋為什麼。
3). 下面的函數有什麼錯誤:
int square(volatile int *ptr)
{ return *ptr * *ptr;
} 下面是答案:
1). 是的。一個例子是只讀的狀態寄存器。它是volatile因為它可能被意想不到地改變。它是const因為程序不應該試圖去修改它。
2). 是的。盡管這並不很常見。一個例子是當一個中服務子程序修該一個指向一個buffer的指針時。
3). 這段代碼的有個惡作劇。這段代碼的目的是用來返指針*ptr指向值的平方,但是,由於*ptr指向一個volatile型參數,編譯器將產生類似下面的代碼:
int square(volatile int *ptr)
{ int a,b;
a = *ptr;
b = *ptr;
return a * b;
} 由於*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結果,這段代碼可能返不是你所期望的平方值!正確的代碼如下:
long square(volatile int *ptr)
{ int a;
a = *ptr;
return a * a;
}
位操作(Bit manipulation)
9. 嵌入式系統總是要用戶對變數或寄存器進行位操作。給定一個整型變數a,寫兩段代碼,第一個設置a的bit 3,第二個清除a 的bit 3。在以上兩個操作中,要保持其它位不變。
對這個問題有三種基本的反應
1). 不知道如何下手。該被面者從沒做過任何嵌入式系統的工作。
2). 用bit fields。Bit fields是被扔到C語言死角的東西,它保證你的代碼在不同編譯器之間是不可移植的,同時也保證了的你的代碼是不可重用的。我最近不幸看到 Infineon為其較復雜的通信晶元寫的驅動程序,它用到了bit fields因此完全對我無用,因為我的編譯器用其它的方式來實現bit fields的。從道德講:永遠不要讓一個非嵌入式的傢伙粘實際硬體的邊。
3). 用 #defines 和 bit masks 操作。這是一個有極高可移植性的方法,是應該被用到的方法。最佳的解決方案如下:
#define BIT3 (0x1<<3)
static int a;
void set_bit3(void)
{ a |= BIT3;
} void clear_bit3(void)
{ a &= ~BIT3;
} 一些人喜歡為設置和清除值而定義一個掩碼同時定義一些說明常數,這也是可以接受的。我希望看到幾個要點:說明常數、|=和&=~操作。
10. 嵌入式系統經常具有要求程序員去訪問某特定的內存位置的特點。在某工程中,要求設置一絕對地址為0x67a9的整型變數的值為0xaa66。編譯器是一個純粹的ANSI編譯器。寫代碼去完成這一任務。
這一問題測試你是否知道為了訪問一絕對地址把一個整型數強制轉換(typecast)為一指針是合法的。這一問題的實現方式隨著個人風格不同而不同。典型的類似代碼如下:
int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa55;
一個較晦澀的方法是:
*(int * const)(0x67a9) = 0xaa55;
即使你的.品味更接近第二種方案,但我建議你在面試時使用第一種方案。
中斷(Interrupts)
11. 中斷是嵌入式系統中重要的組成部分,這導致了很多編譯開發商提供一種擴展—讓標准C支持中斷。具代表事實是,產生了一個新的關鍵字 __interrupt。下面的代碼就使用了__interrupt關鍵字去定義了一個中斷服務子程序(ISR),請評論一下這段代碼的。
__interrupt double compute_area (double radius)
{ double area = PI * radius * radius;
printf(" Area = %f", area);
return area;
}
這個函數有太多的錯誤了,以至讓人不知從何說起了:
1). ISR 不能返回一個值。如果你不懂這個,那麼你不會被僱用的。
2). ISR 不能傳遞參數。如果你沒有看到這一點,你被僱用的機會等同第一項。
3). 在許多的處理器/編譯器中,浮點一般都是不可重入的。有些處理器/編譯器需要讓額處的寄存器入棧,有些處理器/編譯器就是不允許在ISR中做浮點運算。此外,ISR應該是短而有效率的,在ISR中做浮點運算是不明智的。
4). 與第三點一脈相承,printf()經常有重入和性能上的問題。如果你丟掉了第三和第四點,我不會太為難你的。不用說,如果你能得到後兩點,那麼你的被僱用前景越來越光明了。
代碼例子(Code examples)
12 . 下面的代碼輸出是什麼,為什麼?
void foo(void)
{ unsigned int a = 6;
int b = -20;
(a+b > 6) puts("> 6") : puts("<= 6");
}
這個問題測試你是否懂得C語言中的整數自動轉換原則,我發現有些開發者懂得極少這些東西。不管如何,這無符號整型問題的答案是輸出是“>6”。原因是當表達式中存在有符號類型和無符號類型時所有的操作數都自動轉換為無符號類型。因此-20變成了一個非常大的正整數,所以該表達式計算出的結果大於6。這一點對於應當頻繁用到無符號數據類型的嵌入式系統來說是豐常重要的。如果你答錯了這個問題,你也就到了得不到這份工作的邊緣。
13. 評價下面的代碼片斷:
unsigned int zero = 0;
unsigned int compzero = 0xFFFF;
/*1's complement of zero */
對於一個int型不是16位的處理器為說,上面的代碼是不正確的。應編寫如下:
unsigned int compzero = ~0;
這一問題真正能揭露出應試者是否懂得處理器字長的重要性。在我的經驗里,好的嵌入式程序員非常准確地明白硬體的細節和它的局限,然而PC機程序往往把硬體作為一個無法避免的煩惱。
到了這個階段,應試者或者完全垂頭喪氣了或者信心滿滿志在必得。如果顯然應試者不是很好,那麼這個測試就在這里結束了。但如果顯然應試者做得不錯,那麼我就扔出下面的追加問題,這些問題是比較難的,我想僅僅非常優秀的應試者能做得不錯。提出這些問題,我希望更多看到應試者應付問題的方法,而不是答案。不管如何,你就當是這個娛樂吧…
動態內存分配(Dynamic memory allocation)
14. 盡管不像非嵌入式計算機那麼常見,嵌入式系統還是有從堆(heap)中動態分配內存的過程的。那麼嵌入式系統中,動態分配內存可能發生的問題是什麼?
這里,我期望應試者能提到內存碎片,碎片收集的問題,變數的持行時間等等。這個主題已經在ESP雜志中被廣泛地討論過了(主要是 P.J. Plauger, 他的解釋遠遠超過我這里能提到的任何解釋),所有回過頭看一下這些雜志吧!讓應試者進入一種虛假的安全感覺後,我拿出這么一個小節目:下面的代碼片段的輸出是什麼,為什麼?
char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
puts("Got a null pointer");
else
puts("Got a valid pointer");
這是一個有趣的問題。最近在我的一個同事不經意把0值傳給了函數malloc,得到了一個合法的指針之後,我才想到這個問題。這就是上面的代碼,該代碼的輸出是“Got a valid pointer”。我用這個來開始討論這樣的一問題,看看被面試者是否想到庫常式這樣做是正確。得到正確的答案固然重要,但解決問題的方法和你做決定的基本原理更重要些。
Typedef
15. Typedef 在C語言中頻繁用以聲明一個已經存在的數據類型的同義字。也可以用預處理器做類似的事。例如,思考一下下面的例子:
#define dPS struct s *
typedef struct s * tPS;
以上兩種情況的意圖都是要定義dPS 和 tPS 作為一個指向結構s指針。哪種方法更好呢?(如果有的話)為什麼?
這是一個非常微妙的問題,任何人答對這個問題(正當的原因)是應當被恭喜的。答案是:typedef更好。思考下面的例子:
dPS p1,p2;
tPS p3,p4;
第一個擴展為
struct s * p1, p2;
上面的代碼定義p1為一個指向結構的指,p2為一個實際的結構,這也許不是你想要的。第二個例子正確地定義了p3 和p4 兩個指針。
晦澀的語法
16. C語言同意一些令人震驚的結構,下面的結構是合法的嗎,如果是它做些什麼?
int a = 5, b = 7, c;
c = a+++b;
這個問題將做為這個測驗的一個愉快的結尾。不管你相不相信,上面的例子是完全合乎語法的。問題是編譯器如何處理它?水平不高的編譯作者實際上會爭論這個問題,根據最處理原則,編譯器應當能處理盡可能所有合法的用法。因此,上面的代碼被處理成:
c = a++ + b;
因此, 這段代碼持行後a = 6, b = 7, c = 12。
如果你知道答案,或猜出正確答案,做得好。如果你不知道答案,我也不把這個當作問題。我發現這個問題的最大好處是:這是一個關於代碼編寫風格,代碼的可讀性,代碼的可修改性的好的話題
What will print out?
main()
{ char *p1=“name”;
char *p2;
p2=(char*)malloc(20);
memset (p2, 0, 20);
while(*p2++ = *p1++);
printf(“%sn”,p2);
}
Answer:empty string.
What will be printed as the result of the operation below:
main()
{ int x=20,y=35;
x=y++ + x++;
y= ++y + ++x;
printf(“%d%dn”,x,y);
}
Answer : 5794
What will be printed as the result of the operation below:
main()
{ int x=5;
printf(“%d,%d,%dn”,x,x< <2,x>>2);
}
Answer: 5,20,1
What will be printed as the result of the operation below:
#define swap(a,b) a=a+b;b=a-b;a=a-b;
void main()
{ int x=5, y=10;
swap (x,y);
printf(“%d %dn”,x,y);
swap2(x,y);
printf(“%d %dn”,x,y);
}
int swap2(int a, int b)
{ int temp;
temp=a;
b=a;
a=temp;
return 0;
}
Answer: 10, 5
10, 5
What will be printed as the result of the operation below:
main()
{ char *ptr = ” Cisco Systems”;
*ptr++; printf(“%sn”,ptr);
ptr++;
printf(“%sn”,ptr);
}
Answer:Cisco Systems
isco systems
What will be printed as the result of the operation below:
main()
{ char s1[]=“Cisco”;
char s2[]= “systems”;
printf(“%s”,s1);
} Answer: Cisco
What will be printed as the result of the operation below:
main()
{ char *p1;
char *p2;
p1=(char *)malloc(25);
p2=(char *)malloc(25);
strcpy(p1,”Cisco”);
strcpy(p2,“systems”);
strcat(p1,p2);
printf(“%s”,p1);
}
Answer: Ciscosystems
The following variable is available in file1.c, who can access it?:
static int average;
Answer: all the functions in the file1.c can access the variable.
WHat will be the result of the following code?
#define TRUE 0 // some code
while(TRUE)
{
// some code
}
Answer: This will not go into the loop as TRUE is defined as 0.
What will be printed as the result of the operation below:
int x;
int modifyvalue()
{ return(x+=10);
} int changevalue(int x)
{ return(x+=1);
}
void main()
{ int x=10;
x++;
changevalue(x);
x++;
modifyvalue();
printf("First output:%dn",x);
x++;
changevalue(x);
printf("Second output:%dn",x);
modifyvalue();
printf("Third output:%dn",x);
}
Answer: 12 , 13 , 13
What will be printed as the result of the operation below:
main()
{ int x=10, y=15;
x = x++;
y = ++y;
printf(“%d %dn”,x,y);
}
Answer: 11, 16
What will be printed as the result of the operation below:
main()
{ int a=0;
if(a==0)
printf(“Cisco Systemsn”);
printf(“Cisco Systemsn”);
}
Answer: Two lines with “Cisco Systems” will be printed.
;H. 程序員技術面試中,當面試官問「你還有什麼問題」,應該怎麼回答
應聘程序員,在技術面試的時候,結束時面試官通常會問一個問題:你還有什麼問題嗎?眾所周知,面對這個問題不能直接說沒問題了,因為這是你掰回一句或者加深認可的好機會。但是下面這4個問題在技術面試時最好不要問:
1、「我能拿多少工資?」
注意你參加的是技術面試,盡量不要問跟技術不相關的東西,這在技術面試的過程中是一個減分項。一般面試官如果對你有興趣會主動地詢問你的理想薪資。
2、「五險一金有沒有?交通補助有沒有?」
這個問題一般不建議去問,這些問題在技術面試後人事會主動告訴你或者自己主動去詢問人事都可以的,但是在技術面試官面前,問這些跟他本職工作沒有關系的問題會讓面試官覺得不耐煩。
3、「公司經常加班嗎?」
作為開發人員加班的情況肯定是會有的,只是經不經常可能得看公司的實際情況。在面試時問這個問題你可能只是想了解一下公司的加班情況,但卻會讓面試官質疑你的抗壓能力,給面試留下不好的印象。
4、「您覺得我今天能面上嗎?」
有些小夥伴可能急於求職,所以會有些迫切地問這個問題。如果面試官覺得你有希望肯定會給你一些信號,如果面試官不看好你,問這個問題可能讓雙方都比較尷尬。
上面說了4個不該問的問題, 那在面試官問「你還有什麼問題嗎?」時應該問一些什麼問題?
再次點題,在技術面試最好提跟技術相關或跟本職工作相關的的問題。第一,可以問一下關於產品的問題,比如一下產品用的什麼技術,想回去了解一下,或者關於一些新的技術比如大數據、spring boot公司是怎麼用的。這些問題既能讓面試官有興趣回答,又能展現你的知識面。
I. C++經典面試問題
C++經典面試問題
C++經典面試問題分享
1,關於動態申請內存
答:內存分配方式三種:
(1)從靜態存儲區域分配:內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。
全局變數,static變數。
(2)在棧上創建:在執行函數時,函數內局部變數的存儲單元都可以在棧上創建,
函數執行結束時這些存儲單元自動被釋放。
棧內存分配運算內置於處理器的指令集中,效率很高,但是分配的內存容量有限。
(3)用malloc或new申請內存之後,應該立即檢查指針值是否為NULL.防止使用指針值為NULL的內存,
不要忘記為數組和動態內存賦初值。防止將未被初始化的內存作為右值使用。避免數組或指針的下標越界,
特別要當心發生“多1”或者“少1”操作。動態內存的申請與釋放必須配對,防止內存泄漏。
用free或delete釋放了內存之後,立即將指針設置為NULL,防止產生“野指針”。從堆上分配,亦稱動態內存分配。
程序在運行的時候用malloc或new申請任意多少的內存,程序員自己負責在何時用free或delete釋放內存。
動態內存的生存期由程序員決定,使用非常靈活。(int *pArray; int MyArray[6]; pArray = &MyArray[0];)
如果在申請動態內存時找不到足夠大的內存塊,malloc和new將返回NULL指針,
判斷指針是否為NULL,如果是則馬上用return語句終止本函數,
或者馬上用exit(1)終止整個程序的運行,為new和malloc設置異常處理函數。
2,C++指針攻破
答案:指針是一個變數,專門存放內存地址,特點是能訪問所指向的內存
指針本身占據了4個位元組的長度
int **ptr; //指針的類型是 int **
int (*ptr)[3]; //指針的類型是 int(*)[3]
int *(*ptr)[4]; //指針的類型是 int *(*)[4]
ptr++:指針ptr的值加上了sizeof(int)
ptr+=5:將指針ptr的值加上5*sizeof(int)
指針的賦值:
把一個變數的地址賦予指向相同數據類型的指針變數( int a; int *ip; ip=&a; )
把一個指針變數的值賦予指向相同類型變數的另一個指針變數(int a; int *pa=&a; int *pb; pb=pa; )
把數組的首地址賦予指向數組的指針變數(int a[5],*pa; pa=a; 也可寫為:pa=&a[0];)
如果給指針加1或減1 ,實際上是加上或減去指針所指向的數據類型大小。
當給指針加上一個整數值或減去一個整數值時,表達式返回一個新地址。
相同類型的兩個指針可以相減,減後返回的整數代表兩個地址間該類型的實例個數。
int ** cc=new (int*)[10]; 聲明一個10個元素的數組,數組每個元素都是一個int *指針,
每個元素還可以單獨申請空間,因為cc的類型是int*型的指針,所以你要在堆里申請的話就要用int *來申請;
int ** a= new int * [2];//申請兩個int * 型的空間
a[0] = new int[4];////為a的第一個元素申請了4個int 型空間,a[0] 指向了此空間的首地址處
a[1] = new int[3];//為a的第二個元素又申請了3個int 型空間,a[1]指向了此空間首地址處
指針數組初始化賦值:
一維指針開辟空間:char *str;int *arr; scanf("%d",&N);
str=(char*)malloc(sizeof(char)*N);
arr=(int*)malloc(sizeof(int)*N);
二維指針開辟空間:int **arr, i; scanf("%d%d",&row,&col);
arr=(int**)malloc(sizeof(int)*row);
for(i=0;i
arr[i]=(int*)malloc(sizeof(int)*col);
結構體指針數組,例如typedef struct{ char x; int y; }Quan,*QQuan;
定義一個結構體指針數組如:QQuan a[MAX]
for(i=0;i
{
a[i]=(QQuan)malloc(sizeof(Quan));
memset(a[i],0,sizeof(Quan));
}
指針數組賦值
float a[]={100,200,300,400,500};
float *p[5]={&a[0],&a[1],&a[2],&a[3],&a[4]};
char *units[1000];
char get_unit[250];
for(int i=0;i
scanf("%s", get_unit); strcpy(units[i],get_unit);}
3,復雜指針解析:
(1)int (*func)(int *p);
(*func)()是一個函數,func是一個指向這類函數的指針,就是一個函數指針,這類函數具有int*類型的形參,返回值類型是 int。
(2)int (*func)(int *p, int (*f)(int*));
func是一個指向函數的'指針,這類函數具有int *和int (*)(int*)這樣的形參。形參int (*f)(int*),f也是一個函數指針
(3)int (*func[5])(int *p);
func數組的元素是函數類型的指針,它所指向的函數具有int*類型的形參,返回值類型為int。
(4)int (*(*func)[5])(int *p);
func是一個指向數組的指針,這個數組的元素是函數指針,這些指針指向具有int*形參,返回值為int類型的函數。
(5)int (*(*func)(int *p))[5];
func是一個函數指針,這類函數具有int*類型的形參,返回值是指向數組的指針,所指向的數組的元素是具有5個int元素的數組。
注意:
需要聲明一個復雜指針時,如果把整個聲明寫成上面所示的形式,對程序可讀性是一大損害。
應該用typedef來對聲明逐層,分解,增強可讀性,例如對於聲明:int (*(*func)(int *p))[5];
這樣分解:typedef int (*PARA)[5]; typedef PARA (*func)(int *);
例如:int (*(*func)[5][6])[7][8];
func是一個指向數組的指針,這類數組的元素是一個具有5X6個int元素的二維數組,而這個二維數組的元素又是一個二維數組。
typedef int (*PARA)[7][8];
typedef PARA (*func)[5][6];
例如:int (*(*(*func)(int *))[5])(int *);
func是一個函數指針,這類函數的返回值是一個指向數組的指針,
所指向數組的元素也是函數指針,指向的函數具有int*形參,返回值為int。
typedef int (*PARA1)(int*);
typedef PARA1 (*PARA2)[5];
typedef PARA2 (*func)(int*);
4,函數指針詳解
答:函數指針是指向一個函數入口的指針
一個函數指針只能指向一種類型的函數,即具有相同的返回值和相同的參數的函數。
函數指針數組定義:void(*fun[3])(void*); 相應指向類A的成員函數的指針:void (A::*pmf)(char *, const char *);
指向外部函數的指針:void (*pf)(char *, const char *); void strcpy(char * dest, const char * source); pf=strcpy;
5,野指針
答:“野指針”是很危險的,if語句對它不起作用。“野指針”的成因主要有兩種:
(1)指針變數沒有被初始化。指針變數在創建的同時應當被初始化,要麼將指針設置為NULL,要麼讓它指向合法的內存。
char *p = NULL; char *str = (char *) malloc(100);
(2)指針p被free或者delete之後,沒有置為NULL
(3)指針操作超越了變數的作用范圍。所指向的內存值對象生命期已經被銷毀
6,引用和指針有什麼區別?
答:引用必須初始化,指針則不必;引用初始化以後不能改變,指針可以改變其指向的對象;
不存在指向空值的引用,但存在指向控制的指針;
引用是某個對象的別名,主要用來描述函數和參數和返回值。而指針與一般的變數是一樣的,會在內存中開辟一塊內存。
如果函數的參數或返回值是類的對象的話,採用引用可以提高程序的效率。
7,C++中的Const用法
答:char * const p; // 指針不可改,也就說指針只能指向一個地址,不能更改為其他地址,修飾指針本身
char const * p; // 所指內容不可改,也就是說*p是常量字元串,修飾指針所指向的變數
const char * const p 和 char const * const p; // 內容和指針都不能改
const修飾函數參數是它最廣泛的一種用途,它表示函數體中不能修改參數的值,
傳遞過來的參數在函數內不可以改變,參數指針所指內容為常量不可變,參數指針本身為常量不可變
在引用或者指針參數的時候使用const限制是有意義的,而對於值傳遞的參數使用const則沒有意義
const修飾類對象表示該對象為常量對象,其中的任何成員都不能被修改。
const修飾的對象,該對象的任何非const成員函數都不能被調用,因為任何非const成員函數會有修改成員變數的企圖。
const修飾類的成員變數,表示成員常量,不能被修改,同時它只能在初始化列表中賦值。static const 的成員需在聲明的地方直接初始。
const修飾類的成員函數,則該成員函數不能修改類中任何非const成員。一般寫在函數的最後來修飾。
在函數實現部分也要帶const關鍵字.
對於const類對象/指針/引用,只能調用類的const成員函數,因此,const修飾成員函數的最重要作用就是限制對於const對象的使用
使用const的一些建議:在參數中使用const應該使用引用或指針,而不是一般的對象實例
const在成員函數中的三種用法(參數、返回值、函數)要很好的使用;
const在成員函數中的三種用法(參數、返回值、函數)要很好的使用;
不要輕易的將函數的返回值類型定為const;除了重載操作符外一般不要將返回值類型定為對某個對象的const引用;
8,const常量與define宏定義的區別
答:(1) 編譯器處理方式不同。define宏是在預處理階段展開,生命周期止於編譯期。
只是一個常數、一個命令中的參數,沒有實際的存在。
#define常量存在於程序的代碼段。const常量是編譯運行階段使用,const常量存在於程序的數據段.
(2)類型和安全檢查不同。define宏沒有類型,不做任何類型檢查,僅僅是展開。
const常量有具體的類型,在編譯階段會執行類型檢查。
(3) 存儲方式不同。define宏僅僅是展開,有多少地方使用,就展開多少次,不會分配內存。
const常量會在內存中分配(可以是堆中也可以是棧中)
9,解釋堆和棧的區別
答:1、棧區(stack)— 由編譯器自動分配釋放,存放函數的參數值,局部變數的值等。其操作方式類似於數據結構中的棧。
由系統自動分配。聲明在函數中一個局部變數 int b; 系統自動在棧中為b開辟空間 。
只要棧的剩餘空間大於所申請空間,系統將為程序提供內存,否則將報異常提示棧溢出。
在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域,棧的大小是2M。
如果申請的空間超過棧的剩餘空間時,將提示overflow。
棧由系統自動分配,速度較快。但程序員是無法控制的。
函數調用時,第一個進棧的是主函數中後的下一條指令,的地址,然後是函數的各個參數。
在大多數的C編譯器中,參數是由右往左入棧的,然後是函數中的局部變數。注意靜態變數是不入棧的。
堆區(heap) — 一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收 。
注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表,需要程序員自己申請,並指明大小,在c中malloc函數
在C++中用new運算符。首先應該知道操作系統有一個記錄空閑內存地址的鏈表,當系統收到程序的申請時,
另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閑鏈表中。
堆是向高地址擴展的數據結構,是不連續的內存區域。而鏈表的遍歷方向是由低地址向高地址。
堆的大小受限於計算機系統中有效的虛擬內存。
堆是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便
一般是在堆的頭部用一個位元組存放堆的大小。
10,論述含參數的宏和函數的優缺點
(1)函數調用時,先求出實參表達式的值,然後代入形參。而使用帶參的宏只是進行簡單的字元替換
(2)函數調用是在程序運行時處理的,分配臨時的內存單元;而宏展開是在編譯時進行的,在展開時不進行
內存分配,不進行值得傳遞處理,沒有“返回值”概念
(3)對函數中的形參和實參都要定義類型,類型要求一致,如不一致則進行類型轉換。而宏不存在類型問題
(4)調用函數只可得到一個返回值,而用宏則可以設法得到幾個結果
(5)實用宏次數多時,宏展開後源程序變長,沒展開一次源程序增長,函數調用則不會
(6)宏替換不佔用運行時間,只佔編譯時間,而函數調用佔用運行時間
11,C++的空類,默認產生哪些類成員函數?
答:class Empty
{
public:
Empty(); //預設構造函數
Empty(const Empty& ); //拷貝構造函數
~Empty(); //虛構函數
Empty& operator(const Empty& ) //賦值運算符
Empty& operator&(); //取址運算符
const Empty* operator&() const; // 取址運算符 const
}
12,談談類和結構體的區別
答:結構體在默認情況下的成員都是public的,而類在默認情況下的成員是private的。結構體和類都必須使用new創建,
struct保證成員按照聲明順序在內存在存儲,而類不保證。
13,C++四種強制類型轉換
答:(1)const_cast
字面上理解就是去const屬性,去掉類型的const或volatile屬性。
struct SA{ int k}; const SA ra;
ra.k = 10; //直接修改const類型,編譯錯誤 SA& rb = const_cast(ra); rb.k = 10; //可以修改
(2)static_cast
主要用於基本類型之間和具有繼承關系的類型之間的轉換。用於指針類型的轉換沒有太大的意義
static_cast是無條件和靜態類型轉換,可用於基類和子類的轉換,基本類型轉換,把空指針轉換為目標類型的空指針,
把任何類型的表達式轉換成void類型,static_cast不能進行無關類型(如非基類和子類)指針之間的轉換。
int a; double d = static_cast(a); //基本類型轉換
int &pn = &a; void *p = static_cast(pn); //任意類型轉換為void
(3)dynamic_cast
你可以用它把一個指向基類的指針或引用對象轉換成繼承類的對象
動態類型轉換,運行時類型安全檢查(轉換失敗返回NULL)
基類必須有虛函數,保持多態特性才能用dynamic_cast
只能在繼承類對象的指針之間或引用之間進行類型轉換
class BaseClass{public: int m_iNum; virtual void foo(){};};
class DerivedClass:BaseClass{public: char* szName[100]; void bar(){};};
BaseClass* pb = new DerivedClass();
DerivedClass *p2 = dynamic_cast(pb);
BaseClass* pParent = dynamic_cast(p2);
//子類->父類,動態類型轉換,正確
(4)reinterpreter_cast
轉換的類型必須是一個指針、引用、算術類型、函數指針或者成員指針。
主要是將一個類型的指針,轉換為另一個類型的指針
不同類型的指針類型轉換用reinterpreter_cast
最普通的用途就是在函數指針類型之間進行轉換
int DoSomething(){return 0;};
typedef void(*FuncPtr)(){};
FuncPtr funcPtrArray[10];
funcPtrArray[0] = reinterpreter_cast(&DoSomething);
14,C++函數中值的傳遞方式有哪幾種?
答:函數的三種傳遞方式為:值傳遞、指針傳遞和引用傳遞。
15,將“引用”作為函數參數有哪些特點
答:(1)傳遞引用給函數與傳遞指針的效果是一樣的,這時,被調函數的形參就成為原來主調函數的實參變數或者
對象的一個別名來使用,所以在被調函數中形參的操作就是對相應的目標對象的操作
(2)使用引用傳遞函數的參數,在內存中並沒有產生實參的副本,它是直接對實參操作,當參數數據較大時,引用
傳遞參數的效率和所佔空間都好
(3)如果使用指針要分配內存單元,需要重復使用“*指針變數名”形式進行計算,容易出錯且閱讀性較差。
;J. 程序員面試問題及答案
程序員面試問題及答案
程序員是從事程序開發、維護的專業人員。我整理的程序員面試問題及答案,希望大家喜歡!
1、兩柱香問題
題目:有兩柱不均勻的香,每柱香燃燒完需要1個小時,問:怎樣用兩柱香切出一個15分鍾的時間段?這個題的重點就是怎麼切。
解答:將甲香的一頭點著,將乙香的兩頭點著,當乙香燃燒完時,說明已經過了半個小時,同時也說明甲香也正好燃燒了一半,此時,將甲香的另一頭點著,從此時起到甲香完全燒完,正好15分鍾。
2、燈管問題
在房裡有三盞燈,房外有三個開關,在房外看不見房內的情況,你只能進門一次,你用什麼方法來區分那個開關控制那一盞燈?
解答:打開一盞燈10分鍾,關掉,打開第二盞,進去看看哪盞亮,摸摸哪盞熱,熱的是第一個打開的開關開的,亮的是第二個開關開的',另一個就是第三個。
3、兩位盲人問題
他們都各自買了兩對黑襪和兩對白襪,八對襪了的布質、大小完全相同,而每對襪了都有一張商標紙連著。兩位盲人不小心將八對襪了混在一起。 他們每人怎樣才能取回黑襪和白襪各兩對呢?
答案:每一對分開,一人拿一隻,因為襪子不分左右腳的;
4、果凍問題
你有一桶果凍,其中有黃色,綠色,紅色三種,閉上眼睛,同時抓取兩個果凍。抓取多少個就可以確定你肯定有兩個同一顏色的果凍?
答案:2次4個!
5、喝啤酒問題
假如每3個空啤酒瓶可以換一瓶啤酒,某人買了10瓶啤酒,那麼他最多可以喝到多少瓶啤酒?
答案:喝完10瓶後用9個空瓶換來3瓶啤酒(喝完後有4個空瓶)喝完這三瓶又可以換到1瓶啤酒(喝完後有2個空瓶),這時他有2個空酒瓶,如果他能向老闆先借一個空酒瓶,就湊夠了3個空瓶可以換到一瓶啤酒,把這瓶喝完後將空瓶還給老闆就可以了。
所以他最多可以喝10+3+1+1=15瓶
6、三人住旅館
有三個人去住旅館,住三間房,每一間房$10元,於是他們一共付給老闆$30,第二天,老闆覺得三間房只需要$25元就夠了於是叫小弟退回$5給三位客人,誰知小弟貪心,只退回每人$1,自己偷偷拿了$2,這樣一來便等於那三位客人每人各花了九元,於是三個人一共花了$27,再加上小弟獨吞了不$2,總共是$29。可是當初他們三個人一共付出$30那麼還有$1呢?
答案:他們所消費的27元里已經包括小弟的2元了,再加退還的3元=30元。這種題一定不要亂了陣腳,根據一條思路做:這30元現在的分布是:老闆拿25元,伙計拿2元,三人各拿1元,正好!
7、三筐蘋果問題
有三筐水果,一筐裝的全是蘋果,第二筐裝的全是橘子,第三筐是橘子與蘋果混在一起。筐上的標簽都是騙人的,(就是說筐上的標簽都是錯的)你的任務是拿出其中一筐,從裡面只拿一隻水果,然後正確寫出三筐水果的標簽。
答案:從標著「混合」標簽的筐里拿一隻水果,就可以知道另外兩筐裝的是什麼水果了。
分析:從混合的拿出一個來,如果是蘋果,而貼蘋果的筐里有可能是橘子和混合,如果是混合,說明貼橘子的筐里是橘子,不成立(因為前提說了,每個標簽都是錯的)。所以貼蘋果的筐里是橘子,則貼橘子的筐里是混合。
8、汽車加油問題
一輛載油500升的汽車從A開往1000公里外的B,已知汽車每公里耗油量為1升,A處有無窮多的油,其他任何地點都沒有油,但該車可以在任何地點存放油以備中轉,問從A到B最少需要多少油
解答:嚴格證明該模型最優比較麻煩,但確實可證,大膽猜想是解題關鍵。題目可歸結為求數列an=500/(2n 1) n=0,1,2,3......的和Sn什麼時候大於等於1000,解得n>6當n=6時,S6=977.57,所以第一個中轉點離起始位置距離為1000-977.57=22.43公里.所以第一次中轉之前共耗油22.43*(2*7 1)=336.50升此後每次中轉耗油500升,所以總耗油量為7*500 336.50=3836.50升。
9、兩個人猜數問題
教授選出兩個從2到9的數,把它們的和告訴學生甲,把它們的積告訴學生乙,讓他們輪流猜這兩個數, 甲說:「我猜不出」, 乙說:「我猜不出」, 甲說:「我猜到了」, 乙說:「我也猜到了」, 問這兩個數是多少?
解答:3和4。設兩個數為n1,n2,n1> =n2,甲聽到的數為n=n1 n2,乙聽到的數為m=n1*n2,證明n1=3,n2=4是唯一解。證明:要證以上命題為真,不妨先證n=7
1)必要性:
i) n> 5 是顯然的,因為n <4不可能,n=4或者n=5甲都不可能回答不知道
ii) n> 6 因為如果n=6的話,那麼甲雖然不知道(不確定2 4還是3 3)但是無論是2,4還是3,3乙都不可能說不知道(m=8或者m=9的話乙說不知道是沒有道理的)
iii) n <8 因為如果n> =8的話,就可以將n分解成 n=4 x 和 n=6 (x-2),那麼m可以是4x也可以是6(x-2)而4x=6(x-2)的必要條件是x=6即n=10,那樣n又可以分解成8 2,所以總之當n> =8時,n至少可以分解成兩種不同的合數之和,這樣乙說不知道的時候,甲就沒有理由馬上說知道。以上證明了必要性。
2)充分性
當n=7時,n可以分解成2 5或3 4
顯然2 5不符合題意,捨去,容易判斷出3 4符合題意,m=12,證畢
於是得到n=7 m=12 n1=3 n2=4是唯一解。
10、猴子吃香蕉問題
一個小猴子邊上有100 根香蕉,它要走過50 米才能到家,每次它最多搬50 根香蕉,每走1 米就要吃掉一根,請問它最多能把多少根香蕉搬到家裡。
解答:設 小猴從0 走到50, 到A 點時候他可以直接抱香蕉回家了, 可是到A 點時候他至少消耗了3A 的香蕉( 到A, 回0, 到A), 一個限制就是小猴只能抱50 只香蕉, 那麼在A 點小猴最多49 只香蕉.100-3A=49, 所以A=17. 這樣折騰完到家的時候香蕉剩100-3A-(50-A)=50-2A=16.