一、給定一個字符串好比「abcdef」,要求寫個函數變成「defabc」,位數是可變的。html
別人的方法:這個比較簡單,我用的是strcpy和memcpy,而後他問有什麼優化的辦法,我就不知道了。 java
個人方法:node
用兩個指針*front,*rear分別指向字符串的第一個字符和最後一個字符。linux
如下是代碼:程序員
#include<stdio.h> #include<string.h> int main(void){ char s[] = "abcdefa";//若是是char *s ,則後面不能修改其指向的內容。緣由是: //char指針指向文本字符串,能夠認爲char指針是指向const對象的指針;char數組名,能夠認爲是常量指針,不容許修改指向 char *front,*rear = s; while(*rear != NULL) rear ++; rear--; while(front != rear){ if(*front != *rear){ //若是兩個字符相等,則不須要互換 char temp = *front; *front = *rear; *rear = temp; } front++; rear--; } printf("%s",&s); return 0; }
二、socket過程就是socket的server和client整個流程寫下來,這個仍是沒啥問題的。 面試
詳見:http://blog.csdn.net/heyutao007/article/details/6588302算法
三、數據結構二叉樹的遍歷,給了個二叉樹,前序、中序、後序寫出來,這個沒什麼難度。sql
四、樹的層次遍歷,這個開始真忘了,想了半天才想起來用隊列。而後他又讓我詳細寫出入隊出隊的過程,總之仍是搞定了。 數據庫
這顆二叉樹的層次遍歷的過程:假設一個隊列Q,首先根節點A入隊列,接着取對頭元素,即A,將A的子節點B、C前後入隊列,再次取對頭元素,即B,而後將B的子節點D、#入隊列。重複取出對頭元素,將對頭元素入隊列的過程。直到隊列中的數據爲空,遍歷結束。express
五、兩圓相切轉圏問題——一個小圓半徑是1釐米,一個大圓半徑是5釐米,小圓沿着大圓轉圈,請問要轉幾圈能夠轉完大圈?這個問題在行測題作過,就是公轉自轉的問題,無論大小圓半徑是多少,外切轉圏要轉R/r+1圏,內切轉圏轉R/r-1圈。
一、二叉樹的前序遍歷的遞歸和非遞歸的可執行程序。
遞歸容易實現。
非遞歸的實現須要藉助棧來實現
//二叉樹的遍歷 //首先是遞歸實現: //先序遍歷 #include <stdio.h> #include "malloc.h" //定義二叉樹的節點 typedef struct BiTNode{ char data; struct BiTNode *lchild;//左子樹 struct BiTNode *rchild;//右子樹 }BiTNode,*BiTree; //先序創建二叉樹 BiTree createBiTree(){ char ch; BiTree T; scanf("%c",&ch); if(ch=='#'){ T = NULL; printf("Null"); } else{ T = (BiTree)malloc(sizeof(BiTNode)); T->data = ch; T->lchild = createBiTree(); T->rchild = createBiTree(); } return T;//返回根節點 } //前序遍歷(遞歸實現) void preOrder(BiTNode *root){ if(root != NULL){ printf("%c,",root->data); preOrder(root->lchild); preOrder(root->rchild); } } //前序遍歷(非遞歸實現) void preOrder2(BiTNode *root){ //初始化棧 stack *s = (stack *)malloc(sizeof(stack)); initStack(s); BiTNode *p = root;//遍歷指針 while(p || !isEmpty(s)){ if(p){ printf("%d ",p->data);//訪問父節點信息 push(s,p);//將父節點入棧 p = p->lchild;//遍歷左子樹 }else{ BiTNode *father = pop(s);//出棧的是p結點父節點 p = father->rchild;//遍歷右子樹 } } } //定義棧 typedef struct stack{ BiTNode nodes[20]; int size; int top;//指向棧頂元素,初始值爲-1 }stack; //初始化stack void initStack(stack *stack){ stack->size = 0; stack->top = -1; } //判斷棧是否爲空 bool isEmpty(stack *stack){ return stack->size==0?true:false; } //獲取棧大小 int getSize(stack *stack){ return stack->size; } //入棧 void push(stack *stack,BiTNode *node){ if(stack->size<20){ stack->top++; stack->nodes[stack->top] = *node; } } //出棧 BiTNode* pop(stack *stack){ if(stack->top >= -1){ return &stack->nodes[stack->top]; } return NULL; } //中序遍歷 void inOrder(BiTNode *root){ if(root != NULL){ inOrder(root->lchild); printf("%c,",root->data); inOrder(root->rchild); } } //後序遍歷 void postOrder(BiTNode *root){ if(root != NULL){ postOrder(root->lchild); postOrder(root->rchild); printf("%c,",root->data); } }
二、寫出快速排序的實現代碼,一個是字符串拼接函數的實現strcat(),還有大數相乘,都是基本題。
2.一、快速排序:
void quick_sort1(int s[], int l, int r) { if (l < r) { int i = AdjustArray(s, l, r);//先成挖坑填數法調整s[] quick_sort1(s, l, i - 1); // 遞歸調用 quick_sort1(s, i + 1, r); } } int AdjustArray(int s[], int l, int r) //返回調整後基準數的位置 { int i = l, j = r; int x = s[l]; //s[l]即s[i]就是第一個坑 while (i < j) { // 從右向左找小於x的數來填s[i] while(i < j && s[j] >= x) j--; if(i < j) { s[i] = s[j]; //將s[j]填到s[i]中,s[j]就造成了一個新的坑 i++; } // 從左向右找大於或等於x的數來填s[j] while(i < j && s[i] < x) i++; if(i < j) { s[j] = s[i]; //將s[i]填到s[j]中,s[i]就造成了一個新的坑 j--; } } //退出時,i等於j。將x填到這個坑中。 s[i] = x; return i; }
三、歸併排序的實現。
public void MergerSort(int[] v, int first, int last) { if (first + 1 < last) { int mid = (first + last) / 2; MergerSort(v, first, mid); MergerSort(v, mid, last); Merger(v, first, mid, last); } } public void Merger(int[] v, int first, int mid, int last) { Queue<int> tempV = new Queue<int>(); int indexA, indexB; //設置indexA,並掃描subArray1 [first,mid] //設置indexB,並掃描subArray2 [mid,last] indexA = first; indexB = mid; //在沒有比較完兩個子標的狀況下,比較 v[indexA]和v[indexB] //將其中小的放到臨時變量tempV中 while (indexA < mid && indexB < last) { if (v[indexA] < v[indexB]) { tempV.Enqueue(v[indexA]); indexA++; } else { tempV.Enqueue(v[indexB]); indexB++; } } //複製沒有比較完子表中的元素 while (indexA < mid) { tempV.Enqueue(v[indexA]); indexA++; } while (indexB < last) { tempV.Enqueue(v[indexB]); indexB++; } int index = 0; while (tempV.Count > 0) { v[first+index] = tempV.Dequeue(); index++; } }
四、文件按a~z編號,aa~az,ba~bz...za...zz...aaa...aaz,aba~abz...這樣的方法進行編號。給定任意一個編號,輸出文件是第幾個文件。並寫出測試方法。簡單,把編號當作26進制,這題就是一個十進制和26進制的進制轉換問題了。
五、編程:兩個鏈表,按升序排序,合併後仍按升序,不許用遞歸,並求複雜度
一、談談你對數據庫中索引的理解
解答:
索引就是加快檢索表中數據的方法。數據庫的索引相似於書籍的索引。在書籍中,索引容許用戶沒必要翻閱完整個書就能迅速地找到所須要的信息。在數據庫中,索引也容許數據庫程序迅速地找到表中的數據,而沒必要掃描整個數據庫。
二、如今普通關係數據庫用得數據結構是什麼類型的數據結構
關係模型(二維表)。
三、索引的優勢和缺點
索引的優勢 1.建立惟一性索引,保證數據庫表中每一行數據的惟一性 2.大大加快數據的檢索速度,這也是建立索引的最主要的緣由 3.加速表和表之間的鏈接,特別是在實現數據的參考完整性方面特別有意義。 4.在使用分組和排序子句進行數據檢索時,一樣能夠顯著減小查詢中分組和排序的時間。 5.經過使用索引,能夠在查詢的過程當中使用優化隱藏器,提升系統的性能。
索引的缺點 1.建立索引和維護索引要耗費時間,這種時間隨着數據量的增長而增長 2.索引須要佔物理空間,除了數據表佔數據空間以外,每個索引還要佔必定的物理空間,若是要創建聚簇索引,那麼須要的空間就會更大 3.當對錶中的數據進行增長、刪除和修改的時候,索引也要動態的維護,下降了數據的維護速度
四、session、cookie和cache的區別是什麼
詳見:http://blog.csdn.net/lonelyrains/article/details/7838074
五、若是有幾千個session,怎麼提升效率?
將session存儲在數據庫中
六、session是存儲在什麼地方,以什麼形式存儲的?
方式 | 優勢 | 缺點 | 應用 | |
存儲在本地機器內存中 | 速度讀取快 | 容易丟失 | 小型網站 | |
存儲在別的電腦中 | 不消耗本地資源 | 若是網絡不通,則Session讀取不到 | 大的網站 | |
存儲在數據庫中 | 存儲量大 | 速度慢 | 用戶不少的網站 |
1、數據結構和算法 一、簡述什麼是hashtable,如何解決hash衝突 二、什麼叫二叉樹,滿二叉樹,徹底二叉樹
四、數組和鏈表有什麼區別,分別用在什麼場合
數組和鏈表都是線性表,但數組是一組元素有序地存儲在連續的內存單元中,而鏈表的節點元素存儲的內存單元並非連續的。
因爲存儲性質,致使數組的查找可根據下標直接定位,而鏈表的查找須要遍歷,所以查找的效率數組比鏈表要高,而插入和刪除一個元素,數組須要平均移動二分之一的元素,而鏈表能夠直接經過斷鏈和指針實現插入和刪除。
對於樹的操做通常用到鏈表,對於圖的操做通常用到數組。
數組應用場景:
一、注重存儲密度;
二、常常作的運算是按序號訪問數據元素;
三、數組更容易實現,任何高級語言都支持;
四、構建的線性表較穩定。
鏈表應用場景:
一、對線性表的長度或者規模難以估計;
二、頻繁作插入刪除操做;
三、構建動態性比較強的線性表。
2、操做系統
一、什麼叫虛擬內存
虛擬內存是計算機系統內存管理的一種技術。它使得應用程序認爲它擁有連續的可用的內存(一個連續完整的地址空間),而實際上,它一般是被分隔成多個物理內存碎片,還有部分暫時存儲在外部磁盤存儲器上,在須要時進行數據交換。
二、塊設備和字符設備有什麼區別
塊設備:。塊設備將信息存儲在固定大小的塊中,每一個塊都有本身的地址。數據塊的大小一般在512字節到32768字節之間。塊設備的基本特徵是每一個塊都能獨立於其它塊而讀寫。磁盤是最多見的塊設備。
字符設備:字符設備按照字符流的方式被有序訪問,像串口和鍵盤就都屬於字符設備。
1.字符設備只能以字節爲最小單位訪問,而塊設備以塊爲單位訪問,例如512字節,1024字節等
2.塊設備能夠隨機訪問,可是字符設備不能夠
3.字符和塊沒有訪問量大小的限制,塊也能夠以字節爲單位來訪問
三、進程和線程的區別
四、簡述TCP網關鏈接交互細節
即TCP三次握手鍊接,四次握手斷開。
3、Lunix
一、寫出10個經常使用的linux命令和參數
一、返回上層目錄:cd ..;二、打印當前目錄:pwd;三、解壓tar.gz:tar -xzvf file.tar.gz 解壓tar:tar -xvf file.tar;四、強制刪除某個文件:rm -rf file;五、重命名/移動文件:mv /dir/file1 /dir2/file1;
更多詳見:http://os.51cto.com/art/201009/223806.htm
二、如何查看磁盤剩餘空間
df -h1 三、如何查看端口是否被佔用
四、如何查看某個進程所佔用的內存
可分爲動態查看和靜態查看,詳見:http://blog.csdn.net/sunlylorn/article/details/6215137
4、程序題(具體題目記不太清了)
一、用兩個線程實現1-100的輸出
public class Test1 { int num = 0; class addThread extends Thread { @Override public void run() { super.run(); while (true) { if (num < 100) addNum(); else break; } } } public synchronized void addNum() { System.out.println("num=" + num++); } public static void main(String[] args) { Test1 test = new Test1(); addThread t1 = test.new addThread(); addThread t2 = test.new addThread(); t1.start(); t2.start(); } }
二、把一個文件夾中全部01結尾的文件前十行內容輸出
package sina; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.RandomAccessFile; public class Test2 { public static void main(String[] args) { print("e:/test"); } private static void print(String pwd) { File dir = new File(pwd); File[] files = dir.listFiles(); for(int i=0;i<files.length;i++){ //遍歷每一個文件 try { RandomAccessFile rf = new RandomAccessFile(files[i], "r"); long len = rf.length(); long start = rf.getFilePointer(); long end = start+len; rf.seek(end-2); if(rf.read() == '0'){ rf.seek(end-1); if(rf.read() == '1'){ //以01結尾的文件 readTop10Lines(files[i]); } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * 讀取文件前10行 * @param f * @throws IOException */ private static void readTop10Lines(File f) throws IOException{ BufferedReader br = new BufferedReader(new FileReader(f)); String temp; StringBuffer sb = new StringBuffer(); temp = br.readLine(); int count = 1; while(temp != null && count<=10){ sb.append(temp); temp = br.readLine(); count++; } System.out.println(sb.toString()); } }
關於文件操做:http://blog.sina.com.cn/s/blog_507e84890100ch8q.html
一、C++和Java最大的區別是什麼?
http://blog.chinaunix.net/uid-12707183-id-2918815.html
二、static、extern、global的做用?(再一次出現了static,上鏡率真高挖~)
http://blog.csdn.net/hackbuteer1/article/details/7487694
三、inline內聯函數是否佔用運行時間?
不會佔用運行時間。 在程序編譯時,編譯器將程序中出現的內聯函數的調用表達式用內聯函數的函數體來進行替換。因爲在編譯時將內聯函數體中的代碼替代到程序中,所以會增長目標程序代碼量,進而增長空間開銷,而在時間開銷上不象函數調用時那麼大,可見它是以目標代碼的增長爲代價來換取時間的節省。
詳見:http://www.cnblogs.com/socrassi/archive/2009/09/09/1563002.html
關於C語言轉換爲機器語言的過分:http://blog.csdn.net/chengocean/article/details/6250779。
思科二面:
一、進程和線程有什麼區別?
進程是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位。線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),可是它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源。
詳見:http://jingyan.baidu.com/article/624e74598efcc834e9ba5a66.html
三、頁面的替換算法都有哪些?
一、理想頁面置換算法(OPT):這是一種理想的頁面替換算法,在實際中不可能實現。該算法的思想是:發生缺頁時,選擇之後永不使用或在最長時間內再也不被訪問的內存頁面予以淘汰。
二、先進先出頁面置換算法(FIFO):選擇最早進入內存的頁面予以淘汰。
三、最近最久未使用算法(LRU):選擇在最近一段時間內最久沒有使用過的頁,把它淘汰。
四、最少使用算法(LFU):選擇到當前時間爲止被訪問次數最少的頁轉換。
補充:磁盤調度算法。
詳見:http://blog.csdn.net/kennyrose/article/details/7532651
操做系統中常見的調度算法:http://blog.chinaunix.net/uid-25132162-id-361291.html
四、用戶態和內核態的區別?
當一個任務(進程)執行系統調用而陷入內核代碼中執行時,咱們就稱進程處於內核運行態(或簡稱爲內核態)。此時處理器處於特權級最高的(0級)內核代碼中執行。當進程處於內核態時,執行的內核代碼會使用當前進程的內核棧。每一個進程都有本身的內核棧。當進程在執行用戶本身的代碼時,則稱其處於用戶運行態(用戶態)。即此時處理器在特權級最低的(3級)用戶代碼中運行。當正在執行用戶程序而忽然被中斷程序中斷時,此時用戶程序也能夠象徵性地稱爲處於進程的內核態。由於中斷處理程序將使用當前進程的內核棧。這與處於內核態的進程的狀態有些相似。
五、平面上N個點 沒兩個點都肯定一條直線 求出斜率最大 那條直線所經過 兩個點 斜率不存在 狀況不考慮 時間效率越高越好 解法:先把N個點按x排序。 斜率k最大值爲max(斜率(point[i],point[i+1])) 0<=i<n-2。 複雜度Nlog(N)。 以3個點爲例,按照x排序後爲ABC,假如3點共線,則斜率同樣,假如不共線,則能夠證實在AB或BC中,必定有一個點的斜率大於AC,一個點的斜率小於AC。
一、關係型數據庫的特色
關係型數據庫,是指採用了關係模型來組織數據的數據庫。
關係模型是在1970年由IBM的研究員E.F.Codd博士首先提出的,在以後的幾十年中,關係模型的概念獲得了充分的發展並逐漸成爲主流數據庫結構的主流模型。
簡單來講,關係模型指的就是二維表格模型,而一個關係型數據庫就是由二維表及其之間的聯繫所組成的一個數據組織。
關係模型中經常使用的概念:
關係型數據庫的優勢:
http://blog.csdn.net/robinjwong/article/details/18502195
二、父類的析構函數爲何要定義爲虛函數
不定義爲虛函數的話,delete父類只釋放了父類的內存空間,而子類的內存空間沒有釋放,形成了內存泄漏。而定義了虛函數則不會形成內存泄漏。
詳見:http://blog.csdn.net/qiurisuixiang/article/details/6926313
三、把一個字符串的大寫字母放到字符串的後面,各個字符的相對位置不變,不能申請額外的空間。 (比較難)
四、快排算法實現程序
http://blog.csdn.net/hackbuteer1/article/details/6568913
五、KMP算法實現程序
http://blog.csdn.net/hackbuteer1/article/details/7319115
六、override和overload的區別
java中,override:在繼承時,子類方法覆蓋父類方法;overload:同一個類中,方法名相同,但參數個數、順序和類型至少其中一個不一樣,則被視爲不一樣的方法。
詳見http://www.cnblogs.com/whgw/archive/2011/10/01/2197083.html
七、編程並實現一個八皇后的解法
八、鏈表的歸併排序
騰訊二面:
一、在數據庫中如何建立一個表
CREATE TABLE table_name
(column_name data_type
{[NULL | NOT NULL]
[PRIMARY KEY | UNIQUE]}
二、建立後如何添加一個記錄、刪除一個記錄
用sql語句:
添加一個記錄:insert stu('id','name') with value(1,'he');
刪除一個記錄:delete from stu where id=1;
三、編寫C++中的兩個類 一個只能在棧中分配空間 一個只能在堆中分配。 (比較難)
四、請編寫實現malloc()內存分配函數功能同樣的代碼。
五、請編寫能直接實現strstr()函數功能的代碼。
KMP算法
六、已知: 每一個飛機只有一個油箱, 飛機之間能夠相互加油(注意是相互,沒有加油機) 一箱油可供一架飛機繞地球飛半圈, 問題:爲使至少一架飛機繞地球一圈回到起飛時的飛機場,至少須要出動幾架飛機?(全部飛機從同一機場起飛,並且必須安全返回機場,不容許中途降落,中間沒有飛機場)
三架飛機足矣。。http://blog.sina.com.cn/s/blog_60c3c90f0100lkhs.html
七、static的做用——再一次出現~
http://blog.csdn.net/hackbuteer1/article/details/7487694
JAVA中的static 修飾符
一、static變量
按照是否靜態的對類成員變量進行分類可分兩種:一種是被static修飾的變量,叫靜態變量或類變量;另外一種是沒有被static修飾的變量,叫實例變量。
二者的區別是:
對於靜態變量在內存中只有一個拷貝(節省內存),JVM只爲靜態分配一次內存,在加載類的過程當中完成靜態變量的內存分配,可用類名直接訪問(方便),固然也能夠經過對象來訪問(可是這是不推薦的)。
對於實例變量,沒建立一個實例,就會爲實例變量分配一次內存,實例變量能夠在內存中有多個拷貝,互不影響(靈活)。
因此通常在須要實現如下兩個功能時使用靜態變量:
在對象之間共享值時
方便訪問變量時
二、靜態方法
靜態方法能夠直接經過類名調用,任何的實例也均可以調用,
所以靜態方法中不能用this和super關鍵字,不能直接訪問所屬類的實例變量和實例方法(就是不帶static的成員變量和成員成員方法),只能訪問所屬類的靜態成員變量和成員方法。
由於實例成員與特定的對象關聯!這個須要去理解,想明白其中的道理,不是記憶!!!
由於static方法獨立於任何實例,所以static方法必須被實現,而不能是抽象的abstract。
例如爲了方便方法的調用,Java API中的Math類中全部的方法都是靜態的,而通常類內部的static方法也是方便其它類對該方法的調用。
靜態方法是類內部的一類特殊方法,只有在須要時纔將對應的方法聲明成靜態的,一個類內部的方法通常都是非靜態的
三、static代碼塊
static代碼塊也叫靜態代碼塊,是在類中獨立於類成員的static語句塊,能夠有多個,位置能夠隨便放,它不在任何的方法體內,JVM加載類時會執行這些靜態的代碼塊,若是static代碼塊有多個,JVM將按照它們在類中出現的前後順序依次執行它們,每一個代碼塊只會被執行一次。例如:
public class Test5 {
private static int a;
private int b;
static{
Test5.a=3;
System.out.println(a);
Test5 t=new Test5();
t.f();
t.b=1000;
System.out.println(t.b);
}
static{
Test5.a=4;
System.out.println(a);
}
public static void main(String[] args) {
// TODO 自動生成方法存根
}
static{
Test5.a=5;
System.out.println(a);
}
public void f(){
System.out.println("hhahhahah");
}
}
運行結果:
3
hhahhahah
1000
4
5
利用靜態代碼塊能夠對一些static變量進行賦值,最後再看一眼這些例子,都一個static的main方法,這樣JVM在運行main方法的時候能夠直接調用而不用建立實例。
八、寫string類的構造,析構,拷貝函數——這題大約出現過4次左右,包括編程和程序填空,程序員面試寶典上有這題,也算是個經典筆試題,出現概率極大~
http://rsljdkt.iteye.com/blog/770072
微軟面試題彙總 http://www.cnblogs.com/qlee/archive/2011/09/16/2178873.html 一、給你一個凸多邊形,你怎麼用一條線,把它分紅面積相等的兩部分 二、有一條數軸,上有一整數點s,點s兩側分別放了兩個機器人,不知道兩個機器人分別距離s的距離,兩機器人不能相互通訊。 如今,給你如下指令: R(往右一格) L(往左一格) IF(S)是否在S點 GOTO A,跳到A代碼段。 設計一套指令給兩個機器人,讓兩個器機能夠最終在某一點相遇。
三、怎麼判斷兩棵二叉樹是不是同構的
四、按層次打印一個二叉樹
五、給你一個數n(最大爲10000),怎麼求其階乘
六、判斷兩個單鏈表是否有交叉
對於僅判斷相交不相交的話:判斷最後一個節點是否相同的辦法並不慢,若是兩個鏈表長度m,n 那麼複雜度O(m+n),這是最優的複雜度
拓展:如何尋找交叉節點:
指針p、q分別遍歷鏈表a、b,假設q先到達NULL(即 假設a 比 b 長),此時從a的頭髮出一個指針t,當p到達NULL時,從b的頭髮出s,當s==t的時候即交點.
一面:
一、set(底層基於紅黑樹實現)的操做;
list,set,map的用法和區別:http://www.cnblogs.com/I-am-Betty/archive/2010/09/06/1819486.html
java中treemap和treeset實現(紅黑樹):http://www.cnblogs.com/liqizhou/archive/2012/09/27/java%E4%B8%ADtreemap%E5%92%8Ctreeset%E5%AE%9E%E7%8E%B0%E7%BA%A2%E9%BB%91%E6%A0%91.html
hashtable和hashmap的區別:
二、手寫快排遞歸與非遞歸實現;
http://blog.csdn.net/hackbuteer1/article/details/6568913
三、KMP原理解釋
http://blog.csdn.net/hackbuteer1/article/details/7319115
四、聚類分類協同過濾算法;
http://blog.csdn.net/wolenski/article/details/7982555
二面: 一、提示詞實現Trie樹+hash 二、最快速度求兩個數組之交集; 三、文章最短摘要生成;
一、試着用最小的比較次數去尋找數組中的最大值和最小值。 解法一: 掃描一次數組找出最大值;再掃描一次數組找出最小值。 比較次數2N-2
解法二: 將數組中相鄰的兩個數分在一組, 每次比較兩個相鄰的數,將較大值交換至這兩個數的左邊,較小值放於右邊。 對大者組掃描一次找出最大值,對小者組掃描一次找出最小值。 比較1.5N-2次,但須要改變數組結構 解法三: 每次比較相鄰兩個數,較大者與MAX比較,較小者與MIN比較,找出最大值和最小值。
一、寫一個字符串插入的函數 二、問了我關於虛函數底層的實現 http://blog.csdn.net/hackbuteer1/article/details/7883531 三、寫了快排、堆排 http://blog.csdn.net/hackbuteer1/article/details/6568913 四、問我TCP、UDP的一些知識 http://blog.csdn.net/hackbuteer1/article/details/6845406 五、還問了我一些Linux的知識 六、讓我實現紅黑樹的刪除操做 http://blog.csdn.net/hackbuteer1/article/details/7760584
一、考察指針int (*p)[10]和int *p[10]的區別,用法
二、sizeof(),strlen()的區別和用法
2.一、sizeof()是操做符,strlen()是函數;
2.二、sizeof後面跟的是類型或者函數名,strlen的參數只能是char*;
2.三、sizeof返回的是字節大小,strlen返回的是字符個數。
三、堆、棧的區別和用法
3.一、
棧(stack):由編譯器自動分配釋放,存放函數的參數和局部變量的值。其操做方式相似於數據結構中的棧(先進後出)
堆(heap):通常用程序員經過malloc自動分配,也必須由程序員free釋放所佔用的內存。
3.2
棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思
是棧頂的地址和棧的最大容量是系統預先規定好的,在 WINDOWS下,棧的大小是2M(也有的
說是1M,總之是一個編譯時就肯定的常數),若是申請的空間超過棧的剩餘空間時,將提示
overflow。所以,能從棧得到的空間較小。
堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是因爲系統是用鏈表來存儲的
空閒內存地址的,天然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限
於計算機系統中有效的虛擬內存。因而可知,堆得到的空間比較靈活,也比較大。
四、多繼承的優勢與缺點
多重繼承的優勢是對象能夠調用多個基類中的接口。
多重繼承的缺點是容易出現繼承向上的二義性。
詳見:http://blog.csdn.net/jandunlab/article/details/14110117
五、(1)IO2:30ms, CPU 20ms, IO1 20ms, CPU 30ms
(2) IO1 20ms, CPU 20ms, IO2 10ms
(3) CPU 30ms, IO1 20ms
求三種狀況的CPU和IO佔用率
網新恆天二面:
一、內聯函數與宏的區別
1.一、內聯函數在運行時可調試,而宏定義不能夠;
1.二、編譯器會對內聯函數的參數類型作安全檢查或自動類型轉換(同普通函數),而宏定義則不會;
1.三、內聯函數能夠訪問類的成員變量,宏定義則不能;
詳情:http://blog.csdn.net/gao675597253/article/details/7397373
二、與信號量相關知識的考察,具體題目記不清了,反正知道基本概念就會作
詳見:http://blog.csdn.net/sunlovefly2012/article/details/9396201
三、填空,考察頁式虛擬內存的缺頁狀況,也是知道這部分知識點就會作的題
即頁面替換算法。
一、理想頁面置換算法(OPT):這是一種理想的頁面替換算法,在實際中不可能實現。該算法的思想是:發生缺頁時,選擇之後永不使用或在最長時間內再也不被訪問的內存頁面予以淘汰。
二、先進先出頁面置換算法(FIFO):選擇最早進入內存的頁面予以淘汰。
三、最近最久未使用算法(LRU):選擇在最近一段時間內最久沒有使用過的頁,把它淘汰。
四、最少使用算法(LFU):選擇到當前時間爲止被訪問次數最少的頁轉換。
四、類的繼承相關知識點的考察,是一道程序輸出分析題
五、棧的類的成員函數的實現,程序填空題。
六、模板函數與函數模板的區別
七、函數模板與類模板的區別
一、數組,鏈表的優缺點:這個問題比較簡單不過我本身常常會忽略的一點是數組是固定空間,鏈表是可變空間
數組和鏈表都是線性表,但數組是一組元素有序地存儲在連續的內存單元中,而鏈表的節點元素存儲的內存單元並非連續的。
因爲存儲性質,致使數組的查找可根據下標直接定位,而鏈表的查找須要遍歷,所以查找的效率數組比鏈表要高,而插入和刪除一個元素,數組須要平均移動二分之一的元素,而鏈表能夠直接經過斷鏈和指針實現插入和刪除。
對於樹的操做通常用到鏈表,對於圖的操做通常用到數組。
數組應用場景:
一、注重存儲密度;
二、常常作的運算是按序號訪問數據元素;
三、數組更容易實現,任何高級語言都支持;
四、構建的線性表較穩定。
鏈表應用場景:
一、對線性表的長度或者規模難以估計;
二、頻繁作插入刪除操做;
三、構建動態性比較強的線性表。
二、a[N][20]輸入N個長度不超過20的字符串,比較這些字符串中是否有徹底相同的字母,且相同字母數是否相等。如何改進該算法,下降複雜度。
三、黑:A Q 4
紅:J 8 4 2 7 3
梅:K Q 5 4 6
方:A 5
有以上16張撲克牌老闆從中選擇了一張,以後把這張牌的點數告訴了員工甲,把花色告訴了員工乙。以後按以上方式將16張牌平攤在桌面上。
————甲說:我不知道這張牌是什麼。
————乙說:我知道你不知道。
————甲說:我如今知道了。
————乙說:我也知道了。
這張牌是什麼?
應該是方5.
3.一、從甲的第一句話能夠分析,這張牌不是J、八、二、七、三、K、6。
3.二、從乙的第一句話能夠分析,這張牌不是紅或者梅。
3.三、從甲的第二句話能夠分析,這張牌不是A。其實甲在說謊,他還不肯定是黑Q、4仍是方5。
3.四、從乙的第二句話能夠分析,這張牌就是方5,由於黑中有兩個Q和4,而方只有一個5。
四、A:M*M矩陣,求字符串S是否存在A的連續對角線上。(這題應該有涉及到一個之字二維矩陣方面的知識) A若爲內存裝不下的大矩陣該如何處理?
五、系統接收數據包32字節,第1字節爲優先級,其他爲數據。設計一個調度算法 (1)優先級高的先處理 (2)同等條件下,請求次數多的先處理 (3)優先級高的必定比優先級低的先處理 寫出所用的數據結構的定義,計算空間容量。
一、各類排序算法的比較次數
二、static、auto未初始化的初始值 http://blog.csdn.net/hackbuteer1/article/details/7487694
三、x*=y+8,給出x,y的值,求該表達式計算後兩者的值
x=1,y=2,x*=y+8後,y=2,x=10。
四、enum類型的default賦值規則
enum enumType {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};
枚舉量Monday、Tuesday等的值默認分別爲0-6,咱們能夠顯式的設置枚舉量的值:
enum enumType {Monday=1, Tuesday=2, Wednesday=3, Thursday=4, Friday=5, Saturday=6, Sunday=7};
指定的值必須是整數!
詳情:http://jingyan.baidu.com/article/e75aca85526c1b142edac6d9.html
五、定義函數F(int x){return (x*x);} 求F(3+5)
F(3+5)=64
六、fgets(s,n,f)函數的功能
原型是char *fgets(char *s, int n, FILE *stream);
從流中讀取n-1個字符,除非讀完一行,參數s是來接收字符串,若是成功則返回s的指針,不然返回NULL。
形參註釋:*string結果數據的首地址;n-1:一次讀入數據塊的長度,其默認值爲1k,即1024;stream文件指針
說得簡單一點就是從f這個文件輸入流中讀取n-1個字符,存到s中。
若是一行的字符數小於n-1,那麼就是一行的字符數,因此應該理解爲不超過n-1,若是一行的長度大於n-1,就是n-1個字符
七、定義*s="ab\0cdef",輸出該字符能夠看到什麼結果
ab。由於priintf函數以\0爲字符串結束標記。
八、仍是static相關知識——在此說明一下static這個關鍵字至關重要,在筆試中出現率爲100%,在面試中出現率爲50%。
http://blog.csdn.net/hackbuteer1/article/details/7487694
JAVA中的static 修飾符
一、static變量
按照是否靜態的對類成員變量進行分類可分兩種:一種是被static修飾的變量,叫靜態變量或類變量;另外一種是沒有被static修飾的變量,叫實例變量。
二者的區別是:
對於靜態變量在內存中只有一個拷貝(節省內存),JVM只爲靜態分配一次內存,在加載類的過程當中完成靜態變量的內存分配,可用類名直接訪問(方便),固然也能夠經過對象來訪問(可是這是不推薦的)。
對於實例變量,沒建立一個實例,就會爲實例變量分配一次內存,實例變量能夠在內存中有多個拷貝,互不影響(靈活)。
因此通常在須要實現如下兩個功能時使用靜態變量:
在對象之間共享值時
方便訪問變量時
二、靜態方法
靜態方法能夠直接經過類名調用,任何的實例也均可以調用,
所以靜態方法中不能用this和super關鍵字,不能直接訪問所屬類的實例變量和實例方法(就是不帶static的成員變量和成員成員方法),只能訪問所屬類的靜態成員變量和成員方法。
由於實例成員與特定的對象關聯!這個須要去理解,想明白其中的道理,不是記憶!!!
由於static方法獨立於任何實例,所以static方法必須被實現,而不能是抽象的abstract。
例如爲了方便方法的調用,Java API中的Math類中全部的方法都是靜態的,而通常類內部的static方法也是方便其它類對該方法的調用。
靜態方法是類內部的一類特殊方法,只有在須要時纔將對應的方法聲明成靜態的,一個類內部的方法通常都是非靜態的
三、static代碼塊
static代碼塊也叫靜態代碼塊,是在類中獨立於類成員的static語句塊,能夠有多個,位置能夠隨便放,它不在任何的方法體內,JVM加載類時會執行這些靜態的代碼塊,若是static代碼塊有多個,JVM將按照它們在類中出現的前後順序依次執行它們,每一個代碼塊只會被執行一次。例如:
public class Test5 {
private static int a;
private int b;
static{
Test5.a=3;
System.out.println(a);
Test5 t=new Test5();
t.f();
t.b=1000;
System.out.println(t.b);
}
static{
Test5.a=4;
System.out.println(a);
}
public static void main(String[] args) {
// TODO 自動生成方法存根
}
static{
Test5.a=5;
System.out.println(a);
}
public void f(){
System.out.println("hhahhahah");
}
}
運行結果:
3
hhahhahah
1000
4
5
利用靜態代碼塊能夠對一些static變量進行賦值,最後再看一眼這些例子,都一個static的main方法,這樣JVM在運行main方法的時候能夠直接調用而不用建立實例。
九、數據庫中索引,簇索引,非簇,惟一,複合,覆蓋索引的區別
詳解:http://sunct.iteye.com/blog/1933511
圖文理解:http://www.jb51.net/article/29693.htm
補充視圖的相關概念:http://www.cnblogs.com/GISDEV/archive/2008/02/13/1067817.html
十、SQL語句和範式是對數據庫有要求的公司筆試必考點之一
SQL語句:sql內鏈接和外鏈接。內鏈接就是表結果集的交集,而外鏈接是表結果集的並集。
補充:JVM類加載機制-http://blog.csdn.net/a19881029/article/details/17068191
阿里巴巴B2B二面
一、通配符的含義
通配符是一種特殊語句,主要有星號(*)和問號(?),用來模糊搜索文件。
二、死鎖的基本知識——死鎖是各大筆試面試中出現率50%的知識點
產生死鎖的緣由主要是:
(1) 由於系統資源不足。
(2) 進程運行推動的順序不合適。
(3) 資源分配不當等。
若是系統資源充足,進程的資源請求都可以獲得知足,死鎖出現的可能性就很低,不然
就會因爭奪有限的資源而陷入死鎖。其次,進程運行推動順序與速度不一樣,也可能產生死鎖。
產生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已得到的資源保持不放。
(3) 不剝奪條件:進程已得到的資源,在末使用完以前,不能強行剝奪。
(4) 循環等待條件:若干進程之間造成一種頭尾相接的循環等待資源關係。
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之
一不知足,就不會發生死鎖。
死鎖的解除與預防:
理解了死鎖的緣由,尤爲是產生死鎖的四個必要條件,就能夠最大可能地避免、預防和
解除死鎖。因此,在系統設計、進程調度等方面注意如何不讓這四個必要條件成立,如何確
定資源的合理分配算法,避免進程永久佔據系統資源。此外,也要防止進程在處於等待狀態
的狀況下佔用資源。所以,對資源的分配要給予合理的規劃。
三、信號量P、V原語的相關知識點
詳見:http://blog.csdn.net/sunlovefly2012/article/details/9396201
四、有向圖的鄰接表表示
//有向圖的鄰接表表示法 #include <stdio.h> #include <malloc.h> #define MAX_VERTEX_NUM 50//定義圖的最大頂點數 typedef char VertexData; typedef struct EdgeNode//邊表結點 { int adjvex;//鄰接點域 VertexData data; struct EdgeNode *next;//邊結點所對應的下一個邊結點 }EdgeNode; typedef struct VertexNode//定點表結點 { VertexData data; EdgeNode *firstedge;//頭結點所對應的第一個邊結點 }VertexNode; typedef struct AdjList { int VexNum,ArcNum;//定義圖的頂點數和邊數 VertexNode vertex[MAX_VERTEX_NUM];//定義頭結點數組 }AdjList; void CreateGraph(AdjList *adj) { int e,s,d,n,i; char c; EdgeNode *q = NULL; printf("輸入頂點數\n"); scanf("%d",&n); printf("輸入邊數\n"); scanf("%d",&e); adj->VexNum=n; adj->ArcNum = e; //初始化表頭結點 for(i=1;i<=n;i++){ printf("輸入第%d個頂點的頂點名稱:\n",i); //輸入流中還有殘留的字符,getchar()會接受那個字符。能夠在調用getchar()以前用fflush(stdin)刷新一下輸入緩衝區。 fflush(stdin); c = getchar(); adj->vertex[i].data=c;//頂點名稱,是一個字符 adj->vertex[i].firstedge = NULL; } for(i=1;i<=e;i++){ printf("輸入第%d條邊的起點和終點:\n",i); scanf("%d %d",&s,&d);//輸入邊的起始和終止 q=(EdgeNode *)malloc(sizeof(EdgeNode));//建立一個表結點 if(q==NULL) return; q->adjvex=d; q->next = adj->vertex[s].firstedge;//新加入的結點都是頭結點以後, //原來在頭結點以後的結點要後移 adj->vertex[s].firstedge = q; } } void DisplayGraph(AdjList *adj) { int n=adj->VexNum;//頂點個數,後面要遍歷每個點點 EdgeNode *q=NULL; int i; for(i=1;i<=n;i++) { q=adj->vertex[i].firstedge; if(q!=NULL) { printf("從結點%c出發的邊有:",adj->vertex[i].data); while(q!=NULL) { printf("%c->%c",adj->vertex[i].data,adj->vertex[q->adjvex].data); q=q->next; } } } } void main() { AdjList *adj=(AdjList *)malloc(sizeof(AdjList)); CreateGraph(adj); DisplayGraph(adj); }
五、STL中迭代器的工做原理,迭代器與普通指針有什麼區別?
迭代器和指針相同的地方: 一、指針和iterator都支持與整數進行+,-運算,並且其含義都是從當前位置向前或者向後移動n個位置 二、指針和iterator都支持減法運算,指針-指針獲得的是兩個指針之間的距離,迭代器-迭代器獲得的是兩個迭代器之間的距離 三、經過指針或者iterator都可以修改其指向的元素 經過上面這幾點看,二者真的很像,可是二者也有着下面的幾個不一樣地方 一、out操做符能夠直接輸出指針的值,可是對迭代器進行在操做的時候會報錯。經過看報錯信息和頭文件知道,迭代器返回的是對象引用而不是對象的值,因此cout只能輸出迭代器使用*取值後的值而不能直接輸出其自身。 二、指針能指向函數而迭代器不行,迭代器只能指向容器 這就說明了迭代器和指針實際上是徹底不同的概念來的。指針是一種特殊的變量,它專門用來存放另外一變量的地址,而迭代器只是參考了指針的特性進行設計的一種STL接口。 筆者曾在網上看到這樣一種說法:迭代器是廣義指針,而指針知足全部迭代器要求。迭代器是STL算法的接口,而指針是迭代器,所以STL算法可使用指針來對基於指針的非STL容器進行操做。 筆者以爲上面說法也有幾分道理,可是到底正不正確就留給看官本身判斷了。可是有一點但願你們注意的是:千萬不要把指針和迭代器搞混了。也許某些編譯器使用指針來實現迭代器以致於有些人會誤覺得指針和迭代器是一個概念來的。
六、什麼是友元? 七、delete、new的用法 八、typename的用法
九、編程判斷一個數是否爲2的冪
思路:2,4,8,16,32....都是2的n次冪
轉換爲二進制分別爲:
10 100 1000 10000 100000
這些數減1後與自身進行按位與,若是結果爲0,表示這個數是2的n次冪
01 011 0111 01111 011111
10&01 = 0 100&011 = 0 1000&0111 = 0 10000&01111 = 0 100000&011111 = 0
#include <stdio.h> /* 判斷一個整數是否爲2的次方冪 */ bool fun(int v) { bool flag = 0; if((v>0)&&(v&(v-1))==0) flag = 1; return flag; } int main(void) { int a; printf("請輸入1個32位的整數:"); scanf("%d",&a); if(fun(a)) printf("這個數是2次方冪\n"); else printf("這個數不是2次方冪\n"); return 0; }
十、你怎樣從新改進和設計一個ATM銀行自動取款機?
10.一、用指紋識別、人臉識別來替代密碼輸入;
10.二、語音交互來代替傳統按鍵式的人機交互方式。
十二、10000Mbps萬兆交換機怎麼實現?
1三、操做符重載的相關知識點,大題,具體記不清了
一、打印漢諾塔移動步驟,而且計算複雜度
二、計算兩個字符串的是否類似(字符的種類,和出現次數相同)
編程之美中的一道經典的動態規劃題目——計算兩個字符串的類似度
public class StringSimilar { public int fun(String source,String target){ int i,j; int[][] d = new int[source.length()+1][target.length()+1]; for(i=1;i<source.length()+1;i++){/*初始化臨界值*/ d[i][0]=i; } for(j=1;j<target.length()+1;j++){/*初始化臨界值*/ d[0][j]=j; } for(i=1;i<source.length()+1;i++){/*動態規劃填表*/ for(j=1;j<target.length()+1;j++){ if(source.substring(i-1, i).equals(target.substring(j-1, j))){ d[i][j]=d[i-1][j-1];/*source的第i個和target的第j個相同時*/ }else{/*不一樣的時候則取三種操做最小的一個*/ d[i][j]=min(d[i][j-1]+1,d[i-1][j]+1,d[i-1][j-1]+1); } } } return d[source.length()][target.length()]; } private int min(int i, int j, int k) { int min = i<j?i:j; min = min<k?min:k; return min; } public static void main(String[] args) { StringSimilar ss = new StringSimilar(); System.out.println(ss.fun("SNOWY", "SUNNY"));//3 System.out.println(ss.fun("a", "b"));//1 System.out.println(ss.fun("abdd", "aebdd"));//1 System.out.println(ss.fun("travelling", "traveling"));//1 } }
三、定義二叉樹,節點值爲int,計算二叉樹中的值在[a,b]區間的節點的個數
四、動態規劃題:一條路有k可坑,每次能跳平方數步長(1 4 9 16。。),不能跳到坑裏,從a跳到b最少幾步?
五、給一個整數數組,求數組中重複出現次數大於數組總個數一半的數。
一、對以孩子兄弟連接的樹進行遍歷,不能用遞歸,也不能借助任何輔助空間
二、假設數組B是升序Int數組A循環移若干獲得的位,實現對數組B進行查找的高效算法
step1:從數組的末尾向前遍歷,比較B[i]<B[i-1],若是是,則B[i]就是A[0],記錄下標j=i;
step2:判讀查找數據data,data>B[0],則在B[0]~B[j-1]範圍內經過二分查找查找該data;若是data<B[i],則在B[j]~B[B.length-1]範圍內經過二分查找查找該data;
step3:輸出該data在數組B中的下標
時間複雜度:假設數組長度爲n,查找下標j的時間複雜度爲O(n),查找data的時間複雜爲:O(log2(n)),總的時間複雜度爲O(n+log2(n))=O(n)。
三、只有整數和+-*/四種運算組成的算術表達書,實現其求值
考察的是後綴表達式,運用到棧的知識點。
package stack; public class MyStack { private int maxSize; private int[] stackArray; private int top; public MyStack(int s) { maxSize = s; stackArray = new int[maxSize]; top = -1; } public void push(int c) { stackArray[++top] = c; } public int pop() { return stackArray[top--]; } public int peek() { return stackArray[top]; } public boolean isEmpty() { return (top == -1); } public boolean isFull() { return (top == maxSize - 1); } public static void main(String[] args) { MyStack theStack = new MyStack(10); // theStack.push(10); // theStack.push(20); // theStack.push(30); // theStack.push(40); // theStack.push(50); while (!theStack.isEmpty()) { long value = theStack.pop(); System.out.print(value); System.out.print(" "); } System.out.println(""); } }
package peopleseach; import java.util.Scanner; import stack.MyStack; /** * 後綴表達式 * * @author he * */ public class SuffixExpression { /** * 輸入後綴表達式 * * @param expression * 後綴表達式 */ private static String InputExpression(MyStack stack) { Scanner scanner = new Scanner(System.in); String signStr="";//符號字符串 String str = null; do { System.out.println("請輸入整數或者計算符----輸入q即爲退出"); str = scanner.nextLine(); if (!str.isEmpty() && !"q".equals(str)) { char c = str.charAt(0); //若是是計算符號,則拼接成符號字符串 if(c=='+'||c=='-'||c=='*'||c=='/') signStr+=c; else //若是是整數,則入棧 stack.push(Integer.parseInt(str)); } } while (!"q".equals(str)); return signStr; } /** * 計算後綴表達式 * * @param signStr * 計算符號字符串 */ private static void calculate(MyStack stack, String signStr) { int result=0; for (int i = 0; i < signStr.length(); i++) { char c = signStr.charAt(i); int b = stack.pop(); int a = stack.pop(); switch (c) { case '+': result = a + b; break; case '-': result = a - b; break; case '*': result = a * b; break; case '/': result = a / b; break; } stack.push(result); } System.out.println("計算結果爲:"+result); } /** * @param args */ public static void main(String[] args) { MyStack stack = new MyStack(10); String signStr = InputExpression(stack); calculate(stack, signStr); } }
四、還有一個是考貪心算法的,你讓他們看算法導論那本書,關於fractional knapsack problem的那一段,就是0-1揹包的一種變形;
五、鏈表相鄰元素翻轉,如a->b->c->d->e->f-g,翻轉後變爲:b->a->d->c->f->e->g
六、求正整數n全部可能的和式的組合(如;4=1+1+1+一、1+1+二、1+三、2+1+一、2+2)
一、實現一個atoi函數==>'注意正負號的斷定'
/* * name:xif * coder:xifan@2010@yahoo.cn * time:08.20.2012 * file_name:my_atoi.c * function:int my_atoi(char* pstr) */ int my_atoi(char* pstr) { int Ret_Integer = 0; int Integer_sign = 1; /* * 判斷指針是否爲空 */ if(pstr == NULL) { printf("Pointer is NULL\n"); return 0; } /* * 跳過前面的空格字符 */ while(isspace(*pstr) == 0) { pstr++; } /* * 判斷正負號 * 若是是正號,指針指向下一個字符 * 若是是符號,把符號標記爲Integer_sign置-1,而後再把指針指向下一個字符 */ if(*pstr == '-') { Integer_sign = -1; } if(*pstr == '-' || *pstr == '+') { pstr++; } /* * 把數字字符串逐個轉換成整數,並把最後轉換好的整數賦給Ret_Integer */ while(*pstr >= '0' && *pstr <= '9') { Ret_Integer = Ret_Integer * 10 + *pstr - '0'; pstr++; } Ret_Integer = Integer_sign * Ret_Integer; return Ret_Integer; }
二、翻轉一個句子,其中單詞是正序的
算法:
一、將字符串str[0]和str[str.length-1]互換元素,str[1]和str[str.length-2]互換元素····直到將str翻轉;時間複雜度:O(n/2)
二、再將單詞翻轉。時間複雜度:O(nlog2(n))
package peopleseach; /** * 翻轉一個句子,其中單詞是正序的 * * @author he * */ public class OverturnSentence { private static String overturn(String ss) { char[] sentence = ss.toCharArray(); //將字符串str[0]和str[str.length-1]互換元素,str[1]和str[str.length-2]互換元素····直到將str翻轉;時間複雜度:O(n/2) for(int i=0;i<sentence.length/2;i++){ char temp = sentence[i]; sentence[i] = sentence[sentence.length-1-i]; sentence[sentence.length-1-i] = temp; } System.out.println(new String(sentence)); int start = 0; for(int i=0;i<sentence.length;i++){ if(!((sentence[i] >= 'a'&&sentence[i]<='z') ||(sentence[i] >= 'A'&&sentence[i]<='Z'))){ //若是不是英文字符,說明一個字符完結,即str[start]-str[i-1]組成一個單詞。接着就對該單詞翻轉 for(int j=0;j<(i-start)/2;j++){ char temp = sentence[start+j]; sentence[start+j] = sentence[i-1-j]; sentence[i-1-j] = temp; } start = i+1; } } return new String(sentence); } /** * @param args */ public static void main(String[] args) { System.out.println(overturn("I am a good boy!")); } }
三、二叉樹兩個結點中的最小公共子結點==>求長度,長度之差,遠的先走,再一塊兒走
四、三角陣中從第一行到最後一行(給出搜索方向的限制)找一個連續的最大和。
package peopleseach; /** * @author he * 題目:輸入一個整形數組,數組裏有正數也有負數。數組中連續的一個或多個整數組成一個子數組,每一個子數組都有一個和。 * 求全部子數組的和的最大值。要求時間複雜度爲O(n)。 浙大數據結構課本上有 思路: * 求連續數字之和,當和爲負值,拋棄.當和爲正值,比較其與最大值,如大於,則替換之 */ public class ContinuationMax { /** * 連續的最大和 * @param array 上三角矩陣的壓縮存儲數組 */ public static void findMax(int[] array) { int curMax = 0,max = 0; for(int i=0;i<array.length;i++){ curMax += array[i]; if(curMax < 0) curMax = 0; else if(curMax > max) max = curMax; } //if all data is negative if(max == 0){ max = array[0]; //find the max negative for(int i=1;i<array.length;i++) if(array[i]>max) max = array[i]; } System.out.println("The ContinuationMax is "+max); } /** * @param args */ public static void main(String[] args) { int[][] tarray = new int[][]{ {1, -2, 3, 10},{Integer.MAX_VALUE,-2, -3, 5},{Integer.MAX_VALUE,Integer.MAX_VALUE,6,-7},{Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE,11}}; int n=(1+tarray.length)*tarray.length/2; int[] array = new int[n]; int m = 0; for(int i=0;i<tarray.length;i++) for(int j=i;j<tarray.length;j++){ array[m++] = tarray[i][j]; System.out.println(tarray[i][j]); } findMax(array); } }
五、實現一個STL中的vector中的儘可能多的方法。
六、字符串移動(字符串爲*號和26個字母的任意組合,把*號都移動到最左側,把字母移到最右側並保持相對順序不變),要求時間和空間複雜度最小。
/** ** author :hackbuteer ** 時間複雜度 :O(n);空間複雜度:O(1)
** 注意:從str數組末尾向前遍歷要優於從前向後遍歷 **/ void Arrange(char *str , int n) { int i , k = n-1; for(i = n - 1 ; i >= 0 ; --i) { if(str[i] != '*') { if(str[k] == '*') { str[k] = str[i]; str[i] = '*'; } --k; } } }
七、說說outer join、inner join、left join、right join的區別是什麼?
SQL語句:sql內鏈接和外鏈接。(inner join)內鏈接就是表結果集的交集,外鏈接(outer join)是表結果集的並集。 外鏈接又分爲左鏈接(left join)和右鏈接(right join)。