簡介:以上文章講述的是【SQL調(diào)優(yōu)與設(shè)計(jì)規(guī)范】接下來我總結(jié)一下【C# 面試考核基礎(chǔ)知識】。覺得我還可以的可以加群一起督促學(xué)習(xí)探討技術(shù)。QQ群:1076570504 個人學(xué)習(xí)資料庫http://www.aolanghs.com/ 微信公眾號搜索【歡少的成長之路】
一、簡介
之前的一個某某某自動化公司,我上班的狀態(tài)完全屬于迷惘狀態(tài),天天跑車間測試機(jī)器(類似于車間中級技術(shù)工人),寫代碼的量呢也是屬于那種兩周的活,3天就搞完了。完成任務(wù)的情況下,學(xué)習(xí)一些個人的愛好知識也一直被領(lǐng)導(dǎo)懟。機(jī)緣巧合的情況下我離職了。
離職后,有好幾個老板跟我說直接過去,給我實(shí)習(xí)6K,還是一個外企福利比較好,公司規(guī)模也挺大,讓我忌諱的就是外包!然后我就推掉了。
還有一個老板是之前已經(jīng)發(fā)了offer我推掉了現(xiàn)在又在找我實(shí)習(xí)5K,我還是推掉了。原因就是和離職的公司是一個類型偏向于自動化的(不符合我個人的發(fā)展規(guī)劃)
于是我就是到了這家公司,聊的技術(shù)也有一些,負(fù)載均衡,數(shù)據(jù)庫集群,SQL調(diào)優(yōu),線上項(xiàng)目,Redis緩存,幾千萬數(shù)據(jù)分庫分表操作。挺符合我個人發(fā)展規(guī)劃的!
實(shí)習(xí)一個月考核轉(zhuǎn)正了!說實(shí)話,時間太短,業(yè)務(wù)還是不夠透徹!估計(jì)涼涼!
二、轉(zhuǎn)正考核C# 基礎(chǔ)知識
3月23號轉(zhuǎn)正考核,這是我考核前整理的學(xué)習(xí)心得,幫助自己的同時,也想幫助一些在校的學(xué)生接觸的知識是偏公司的!而不是學(xué)校的基礎(chǔ)。
裝箱和拆箱
裝箱:值類型轉(zhuǎn)引用類型
拆箱:引用類型轉(zhuǎn)值類型,拆箱前必須要有裝箱過程
+的作用有哪些
做運(yùn)算符,拼接字符串。+會導(dǎo)致隱式轉(zhuǎn)換,所以使用時應(yīng)注意
涉及到了轉(zhuǎn)換我們可以聊一下顯式類型轉(zhuǎn)換以及隱式類型轉(zhuǎn)換
顯式轉(zhuǎn)換以及隱式轉(zhuǎn)換
隱式類型轉(zhuǎn)換 這些轉(zhuǎn)換是 C# 默認(rèn)的以安全方式進(jìn)行的轉(zhuǎn)換, 不會導(dǎo)致數(shù)據(jù)丟失。例如,從小的整數(shù)類型轉(zhuǎn)換為大的整數(shù)類型,從派生類轉(zhuǎn)換為基類。
顯式類型轉(zhuǎn)換 顯式類型轉(zhuǎn)換,即強(qiáng)制類型轉(zhuǎn)換。顯式轉(zhuǎn)換需要強(qiáng)制轉(zhuǎn)換運(yùn)算符,而且強(qiáng)制轉(zhuǎn)換會造成數(shù)據(jù)丟失。
換句話說(白話文)
顯式 double8個字節(jié)轉(zhuǎn)int4個字節(jié)會造成數(shù)據(jù)丟失,比如double(5.6666)轉(zhuǎn)int會變成5造成丟失了0.6666.這就是顯式轉(zhuǎn)換也稱為強(qiáng)制轉(zhuǎn)換。
隱式 int4個字節(jié)轉(zhuǎn)double8個字節(jié)可以直接使用,int(5)轉(zhuǎn)double會變成double(5)有可能5后面還有幾個0呢 精度變高了呢!
this和super的區(qū)別
this 代表的是本類對象的引用,誰調(diào)用,就代表誰;
super代表的是父類存儲空間的標(biāo)識(可以理解成父類的引用,可以操作父類的成員)
簡單明了!
送分題break,continue,return區(qū)別
return 跳出此語句塊
break 跳出本次循環(huán),執(zhí)行下面的語句,只能跳出一層循環(huán)
continue 跳出本次循環(huán)執(zhí)行下次循環(huán)
值類型和引用類型
存儲方式 值類型存儲在內(nèi)存棧中,引用類型存儲在內(nèi)存堆中,地址存放在內(nèi)存棧中
①引用類型可以派生出新的類型,而值類型不行,因?yàn)橹殿愋褪敲芊獾摹?br style="box-sizing: border-box;">②引用類型可以包含null但是值類型不行
③引用類型變量的賦值只是復(fù)制對象的引用而不復(fù)制對象的本身,而將一個值類型變量復(fù)制賦給另一個值類型變量時,將復(fù)制包含的值
常量和變量的區(qū)別
常量為只讀的不可更改值,而變量是可以更改值的;聲明常量關(guān)鍵字:const
場景:常量用于全局的一些路徑一改全改,或者數(shù)據(jù)庫字符串,或者范圍的閾值等
變量分全局變量和局部變量。全局一定要少定義!全局很多的話可以考慮利用單例模式統(tǒng)一管理整個項(xiàng)目的全局變量。
常量分靜態(tài)常量和動態(tài)常量。它們有不同的特性,錯誤的使用不僅會損失效率,還可能造成錯誤。相比之下,靜態(tài)常量在速度上會稍稍快一些,但是靈活性卻比動態(tài)常量差很多。
//靜態(tài)常量(隱式是靜態(tài)的)
public const int compiletimeConstant = 1;
//動態(tài)常量
public static readonly runtimeConstant = 1;
事件中兩個參數(shù)sender,e的作用分別是什么
sender是事件的發(fā)起者,e參數(shù)是事件對象,事件所攜帶的信息
舉個例子,文本框更改事件,只要數(shù)據(jù)更改,就算是一個字符,事件立即會進(jìn)行觸發(fā)。
事件是一種特殊的委托,事件和委托搭配使用的比較頻繁,見下面委托示例!
委托簡單介紹一下
可以參考我之前的文章
普及一下:比如生產(chǎn)系統(tǒng),測試零部件是否合格的,不管是按工序測量還是按零件測量都需要很強(qiáng)的數(shù)據(jù)實(shí)時更改需求,所以這里可以考慮利用單例模式管理整個項(xiàng)目的委托事件觸發(fā) 例如
private static SysRuntime runTime;
public static SysRuntime GetInstance()
{
if (runTime == null)
runTime = new SysRuntime();
return runTime;
}
#region 窗口管理代碼
/// <summary>
/// 窗體狀態(tài)改變事件
/// </summary>
/// <param name="type"></param>
/// <param name="index"></param>
public delegate void WinDowStaeChange(FormWindowState state);
public event WinDowStaeChange OnWinDowStaeChangeed;
/// <summary>
/// 當(dāng)窗口大小發(fā)送改變時
/// 最大化不會觸發(fā)次事件
/// </summary>
/// <param name="frmname">目標(biāo)窗體名稱</param>
/// <param name="w">寬度</param>
/// <param name="h">高度</param>
public delegate void WinDowSizeChange(string frmname, int w, int h);
public event WinDowSizeChange OnWinDowSizeChangeed;
/// <summary>
/// 子窗體位置發(fā)生改變
/// </summary>
/// <param name="point">最新位置</param>
public delegate void WinDowLocationChange(string frmname, Point point);
public event WinDowLocationChange OnWinDowLocationChangeed;
/// <summary>
/// 子窗體關(guān)閉時
/// </summary>
/// <param name="frmname"></param>
public delegate void WinDowClose(string frmname);
public event WinDowClose OnWinDowClosed;
Lambda簡單介紹一下
可以參考我之前的文章
overload 重載 override 重寫的區(qū)別
override 重寫與 overload 重載的區(qū)別。重載是方法的名稱相同。參數(shù)或參數(shù)類型不同,進(jìn)行多次重載以適應(yīng)不同的需要 override 是進(jìn)行基類中函數(shù)的重寫。實(shí)現(xiàn)多態(tài)。
private、protected、pubic、internal修飾符的訪問權(quán)限
private : 私有成員, 在類的內(nèi)部才可以訪問(只能從其聲明上下文中進(jìn)行訪問)
protected : 保護(hù)成員,該類內(nèi)部和從該類派生的類中可以訪問
public : 公共成員,完全公開,沒有訪問限制
internal: 在同一命名空間內(nèi)可以訪問
什么是受管制(托管)的代碼?
托管代碼。運(yùn)行.NET 公共語言運(yùn)行時CLR的代碼
非托管代碼。不經(jīng)過CLR運(yùn)行。程序員自行分配和釋放內(nèi)存空間
注意!非托管代碼一定要注意內(nèi)存的問題!
ORM
ORM是一種對象關(guān)系映射框架。用于實(shí)現(xiàn)面向?qū)ο缶幊陶Z言里不同類型系統(tǒng)的數(shù)據(jù)之間的轉(zhuǎn)換
建議使用:SqlSugar。
ORM與傳統(tǒng)的數(shù)據(jù)庫訪問技術(shù)相比,
優(yōu)點(diǎn):開發(fā)效率更高,數(shù)據(jù)訪問更抽象、輕便,支持面向?qū)ο蠓庋b
缺點(diǎn):降低程序的執(zhí)行效率,思維固定化
GC是什么? 為什么要有GC?
GC是垃圾收集器。程序員不用擔(dān)心內(nèi)存管理,因?yàn)槔占鲿詣舆M(jìn)行管理。要請求垃圾收集,可以調(diào)用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()
類(class)與結(jié)構(gòu)(struct)的異同?
class分配在內(nèi)存的堆,可以被實(shí)例化,屬于引用類型,可以實(shí)現(xiàn)接口和單繼承其他類,還可以作為基類型。
struct分配在內(nèi)存的棧,屬于值類型,不能作為基類型,但是可以實(shí)現(xiàn)接口
string str1 = null 與 string str2 ="" 區(qū)別?
string str1 = null 是不給他分配內(nèi)存空間,因此str1還不是一個實(shí)例化的對象
string str2 = “” 給它分配長度為空字符串的內(nèi)存空間,因此str2已經(jīng)實(shí)例化
String s = new String(“xyz”);創(chuàng)建了幾個String Object?
兩個對象,一個是“xyx”,一個是指向“xyx”的引用對象s。
abstract class和interface有什么區(qū)別?
abstract 聲明抽象類抽象方法,一個類中有抽象方法,那么這個類就是抽象類了。所謂的抽象方法,就是不含主體(不提供實(shí)現(xiàn)方法),必須由繼承者重寫。因此,抽象類不可實(shí)例化,只能通過繼承被子類重寫。
interface 聲明接口,只提供一些方法規(guī)約,不提供任何實(shí)現(xiàn);不能用public、abstract等修飾,無字段、常量,無構(gòu)造函數(shù)
try里的return和final沖突嗎?介紹一下
try后的finally {}里的code會被執(zhí)行,在return前執(zhí)行。
堆和棧是啥?
上面說了那么多堆那么多棧到底是啥呀。
棧:由編譯器自動分配、釋放。在函數(shù)體中定義的變量通常在棧上。棧內(nèi)存無需我們管理,也不受GC管理。當(dāng)棧頂元素使用完畢,立馬釋放。而堆則需要GC清理。
堆:一般由程序員分配釋放。用new、malloc等分配內(nèi)存函數(shù)分配得到的就是在堆上。堆是無序的,他是一片不連續(xù)的內(nèi)存域,有用戶自己來控制和釋放,
使用引用類型的時候,一般是對指針進(jìn)行的操作而非引用類型對象本身。但是值類型則操作其本身。
using和new這兩個關(guān)鍵字有什么意義
using 引入名稱空間或者使用非托管資源,使用完對象后自動執(zhí)行實(shí)現(xiàn)了IDisposable接口的類的Dispose方法
new 新建實(shí)例或者隱藏父類方法
所以為了提升代碼的內(nèi)存性能,在自己掌控的情況下,使用某一庫對象之類的可以用using。
進(jìn)程和線程的區(qū)別?
進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的單位;
線程是CPU調(diào)度和分派的單位;
一個進(jìn)程可以有多個線程,這些線程共享這個進(jìn)程的資源。
DataReader與Dataset有什么區(qū)別?
DataReader使用時始終占用SqlConnection,在線操作數(shù)據(jù)庫。任何對SqlConnection的操作都會引發(fā)DataReader的異常.因?yàn)镈ataReader每次只在內(nèi)存中加載一條數(shù)據(jù),所以占用的內(nèi)存是很小的…因?yàn)镈ataReader的特殊性和高性能.所以DataReader是只進(jìn)的.你讀了第一條后就不能再去讀取第一條了.。
DataSet則是將數(shù)據(jù)一次性加載在內(nèi)存中.拋棄數(shù)據(jù)庫連接.讀取完畢即放棄數(shù)據(jù)庫連接.因?yàn)镈ataSet將數(shù)據(jù)全部加載在內(nèi)存中.所以比較消耗內(nèi)存.但是確比DataReader要靈活.可以動態(tài)的添加行,列,數(shù)據(jù).對數(shù)據(jù)庫進(jìn)行回傳更新操作
啟動一個線程用run()還是start()?
啟動一個線程用start()方法,使線程所代表的虛擬處理機(jī)處于可運(yùn)行狀態(tài),這意味著它可以由JVM調(diào)度并執(zhí)行,并不意味著線程就會立即運(yùn)行。run()方法可以產(chǎn)生必須退出的標(biāo)志來停止一個線程。
支持多重繼承么?
類之間不支持,接口之間支持。類對接口叫做實(shí)現(xiàn),不叫繼承。
GC
當(dāng)程序需要更多的堆空間時,GC需要進(jìn)行垃圾清理工作,暫停所有線程,找出所有無被引用的對象,進(jìn)行清理,并通知棧中的指針重新指向地址排序后的對象。
GC只能處理托管內(nèi)存資源的釋放,對于非托管資源則不能使用GC進(jìn)行回收,必須由程序員手動回收,例如FileStream或SqlConnection需要調(diào)用Dispose進(jìn)行資源的回收。
CLR
公共語言運(yùn)行庫,負(fù)責(zé)資源管理(包括內(nèi)存分配、程序及加載、異常處理、線程同步、垃圾回收等),并保證應(yīng)用和底層操作系統(tǒng)的分離。
序列化與反序列化
序列化:將對象狀態(tài)轉(zhuǎn)換為可保持或傳輸?shù)母袷降倪^程。將對象實(shí)例的字段及類的名稱轉(zhuǎn)換成字節(jié)流,然后把字節(jié)流寫入數(shù)據(jù)流
反序列化:將流轉(zhuǎn)換為對象。
這兩個過程結(jié)合起來,可以輕松地存儲和傳輸數(shù)據(jù)。
參數(shù)傳遞 ref 與 out 的區(qū)別
ref指定的參數(shù)在函數(shù)調(diào)用時必須先初始化,而out不用
out指定的參數(shù)在進(jìn)入函數(shù)時會清空自己,因此必須在函數(shù)內(nèi)部進(jìn)行初始化賦值操作,而ref不用
總結(jié):ref可以把值傳到方法里,也可以把值傳到方法外;out只可以把值傳到方法外
注意:string作為特殊的引用類型,其操作是與值類型看齊的,若要將方法內(nèi)對形參賦值后的結(jié)果傳遞出來,需要加上ref或out關(guān)鍵字。
淺克隆與深克隆(淺拷貝與深拷貝)
下面簡單介紹一下淺克隆
在淺克隆中,如果原型對象的成員變量是值類型,將復(fù)制一份給克隆對象;如果原型對象的成員變量是引用類型,則將引用對象的地址復(fù)制一份給克隆對象,也就是說原型對象和克隆對象的成員變量指向相同的內(nèi)存地址。簡單來說,在淺克隆中,當(dāng)對象被復(fù)制時只復(fù)制它本身和其中包含的值類型的成員變量,而引用類型的成員對象并沒有復(fù)制。通過實(shí)現(xiàn)ICloneable接口的Clone()方法,并調(diào)用MemberwiseClone()方法來實(shí)現(xiàn)淺克隆
深克隆
在深克隆中,無論原型對象的成員變量是值類型還是引用類型,都將復(fù)制一份給克隆對象,深克隆將原型對象的所有引用對象也復(fù)制一份給克隆對象。簡單來說,在深克隆中,除了對象本身被復(fù)制外,對象所包含的所有成員變量也將復(fù)制。
在C#語言中,如果需要實(shí)現(xiàn)深克隆,可以通過序列化(Serialization)等方式來實(shí)現(xiàn)。序列化就是將對象寫到流的過程,寫到流中的對象是原有對象的一個拷貝,而原對象仍然存在于內(nèi)存中。通過序列化實(shí)現(xiàn)的拷貝不僅可以復(fù)制對象本身,而且可以復(fù)制其引用的成員對象,因此通過序列化將對象寫到一個流中,再從流里將其讀出來,可以實(shí)現(xiàn)深克隆。需要注意的是能夠?qū)崿F(xiàn)序列化的對象其類必須實(shí)現(xiàn)Serializable接口,否則無法實(shí)現(xiàn)序列化操作
String與StringBuffer的區(qū)別
String 對象是不可變對象,每次操作Sting 都會重新建立新的對象來保存新的值。這樣原來的對象就沒用了,就要被垃圾回收非常影響性能。
StringBuffer:是一個可變對象,當(dāng)對他進(jìn)行修改的時候不會像String那樣重新建立對象。它只能通過構(gòu)造函數(shù)來建立。對象被建立以后,在內(nèi)存中就會分配內(nèi)存空間,并初始保存一個null.向StringBuffer中賦值的時候可以通過它的append方法。sb.append(“hello”);
字符串連接操作中StringBuffer的效率要比String高。StringBuffer 的速度幾乎是String 上萬倍
類和結(jié)構(gòu)的區(qū)別?
前者為引用類型,后者為值類型
三、總結(jié)
這是我目前學(xué)習(xí)到以及掌握的C# 基礎(chǔ)知識!
希望各位讀者可以學(xué)到一些知識然后提升自己的薪資水平!
廣度深度都有,全部原創(chuàng),有想了解的也可以評論我會一一回復(fù)
知道的越多,不知道的就越多。找準(zhǔn)方向,堅(jiān)持自己的定位!加油向前不斷前行,終會有柳暗花明的一天!
創(chuàng)作不易,你們的支持就是對我最大認(rèn)可!
文章將持續(xù)更新,我們下期見!QQ群:1076570504 微信公眾號搜索【歡少的成長之路】請多多支持!