座標polarDB,阿里雲數據庫內核組。
自己在過年後光速寫了個小的數據庫當項目,也算是彌補了項目經驗上的不足。
簡歷面
- 編譯器是怎麼優化的
- 手擼內存分配器
通過一個數組來管理資源,需要使用時從數組中分配一個成員,使用完畢後從數組中釋放該成員,釋放後的成員可以被再次分配使用;請實現一個結構用來快速的對資源進行分配和釋放。 - 聊項目
一面
- 說說 const char *ptr 和 char const *ptr的區別
- 寫出一個包含以下元素的結構體的大小
char a;
char b;
double c;
int d;
- static的作用
- 宏和inline區別
- 說說純虛函數和虛函數
- new和malloc區別
- 說出以下代碼每行的作用和運行結果
char *p = (char *) malloc(10);
sizeof(p)= 4
free(p+1)
- 手擼算法:最大子矩陣和,我是用 的做法寫出來的
- 口述算法:N個數,有一個數出現超過N/2,尋找這個數
- 口述算法:鏈表倒數第K數
- 靜態鏈接庫和動態鏈接庫的區別
- epoll和select的作用
- 手擼多線程編程題:隊列取數和放數交替操作(具體的記不太清了)
- 聊項目,因爲自己的項目是實現了一個小的關係型數據庫,正好這是數據庫內核組,於是就…被花式吊打
二面
- 聊大一時候的圖像檢索的項目
- 聊數據庫這個項目
- 手擼算法題:
按段(段內的元素不翻轉)翻轉鏈表:如鏈表 1->2->3->4->5->6->7->8->9,如果段大小爲3,翻轉後爲7->8->9->4->5->6->1->2->3。
注意段大小作爲參數傳入。要求編寫可以運行的測試用例(有main函數和足夠的測試集),注意代碼規範。
三面
- Linux系統怎麼看cache的相關信息
- 什麼情況下內容會存進cache,怎麼看cache的內容
- 聊項目。。。
- 算法題1:找二叉樹最深的節點
- 算法題2:遍歷二叉樹最底層的節點
- 算法題3:在一個無向圖中,如何判斷兩點是否聯通
- 算法題4:在一個有向圖中,如何判斷兩點是否聯通
這一面還是比較簡單的,幾個算法題就是dfs、bfs來回考,判聯通可以用並查集操作一下。
四面
- 聊項目
- 進程和線程區別
- 進程間的通信方式
- 如何調試C++多線程程序
- 聊人生
五面(hr面)
- 自我介紹
- 自己擅長什麼不擅長什麼
- 聊聊ACM經歷
- 說說自己的學校怎麼樣
- 自己成績怎麼樣
- 人生最大的挫折是什麼
個人代碼
因爲阿里伯樂寫代碼是有存檔的,所以就貼一下方便大家指教。
內存分配器
//通過一個數組來管理資源,
//需要使用時從數組中分配一個成員;
//使用完畢後從數組中釋放該成員,釋放後的成員可以被再次分配使用;請實現一個結構用來快速的對資源進行分配和釋放。
// 10000這種數字是跟面試官溝通以後隨便寫的
class memory_manage {
public:
obj* m_malloc() {
obj* p = nullptr;
if(l.size()) {
p = l.front();
l.erase(l.begin());
} else if(cur<10000) {
p = &arr[cur++];
}
return p;
}
void m_free(obj* p) {
l.push_back(p);
}
private:
obj arr[10000];
int cur = 0;
list<obj*> l;
};
最大子矩陣和
N * N
-10 1 2 3
2 3 4 -100
1 2 3 5
0 0 0 0
K*M
和最大的子矩陣
O(N^2)
第一步:矩陣前綴和O(n^2)
第二步:遍歷子矩陣O(n^4)
int a[N+2][N+2];
int sum[N+2][N+2];
void FindMax(int n) {
int cur = 0,ans = 0;
memset(sum,0,sizeof(sum));
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
sum[i][j] = sum[i-1][j] + a[i][j];
}
}
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
cur = 0;
for(int k=1; k<=n; k++) {
cur = cur + (sum[j][k]-sum[i-1][k]);
if(cur<0) cur = 0;
else ans = cur;
}
}
}
return ans;
}
多線程題
mutex g_mutex;
condition_variable cv;
queue<int> q;
bool flag = 0; // 0放,1取
int get() {
lock_guard<mutex> mtx(g_mutex);
cv.wait(mtx,[] {return flag==1;});
int val = q.front();
q.pop();
flag = 0;
cv.notify_one();
return val;
}
void put(int val) {
lock_guard<mutex> mtx(g_mutex);
cv.wait(mtx,[] {return flag==0;});
q.push(val);
flag = 1;
cv.notify_one();
return;
}
花式翻轉鏈表
// 評測題目: 按段(段內的元素不翻轉)翻轉鏈表:如鏈表 1->2->3->4->5->6->7->8->9,
// 如果段大小爲3,翻轉後爲7->8->9->4->5->6->1->2->3。注意段大小作爲參數傳入。
// 要求編寫可以運行的測試用例(有main函數和足夠的測試集),注意代碼規範。
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x):val(x),next(NULL){}
};
struct BlockList {
ListNode *LeftPre,*LeftNow,*RightNow;
BlockList(ListNode* a,ListNode* b){
LeftPre = a;
LeftNow = b;
RightNow = nullptr;
}
};
void PrintList(ListNode* head) {
head = head->next;
while(head!=nullptr) {
cout << head->val << ' ';
head=head->next;
}
cout << endl;
}
ListNode* ReverseList(ListNode* head,int block_size) {
vector<BlockList> Block;
ListNode* p = head;
ListNode* pre = nullptr;
int now_size = -1;
while(p!=nullptr) { //Record each block head
if(now_size>=0 && now_size % block_size==0) {
Block.push_back(BlockList(pre,p));
}
if(now_size>=0 && now_size % block_size==block_size-1 || p->next==nullptr) {
Block.back().RightNow = p;
}
pre = p;
p = p->next;
now_size++;
}
int block_num = Block.size();
for(int i=0;i<block_num/2;i++) {
BlockList left = Block[i];
BlockList right = Block[block_num-i-1];
left.LeftPre->next = right.LeftNow;
ListNode* temp = right.RightNow->next;
right.RightNow->next = left.RightNow->next;
right.LeftPre->next = left.LeftNow;
left.RightNow->next = temp;
}
return head;
}
int main() {
int ListSize,ReverseSize;
cin >> ListSize >> ReverseSize;
if(ListSize==0) {
cout << "Empty List!" << endl;
return 0;
}
ListNode* p = new ListNode(-1);
ListNode* root = p;
for(int i=0,val;i<ListSize;i++) {
cin >> val;
ListNode* q = new ListNode(val);
p->next = q;
p = p->next;
}
ReverseList(root,ReverseSize);
PrintList(root);
return 0;
}
/* 測試用例
9 3
1 2 3 4 5 6 7 8 9
3 1
1 2 3
0 0
2 2
1 2
3 4
1 2 3
5 2
1 2 3 4 5
*/