目录

101. 分现在有10个人被一个魔鬼逮住了。魔鬼对于直接把人 杀掉的方法不感兴趣了。于是,他就想了一个杀人的新花样。 是这样的,一天晚上,魔鬼向着十个人宣布了游戏规则,即 明天早上他要把10个人排成一排,然后从一堆既有无限多 的白帽子混着无限多黑帽子的帽子堆为每个人随机抽取一 顶帽子,给他们10个人都戴上帽子。因为10个人是排成一 排的,所以排在第10个的人可以看到前面9个人帽子的颜 色,排在第9个人可以看到前面8个人的帽子的颜色,…以 此类推。然后,魔鬼会从排在第10个人开始,问他,你头 上的帽子的颜色是白色还是黑色,如果答对了,就放他走; 如果答错了,就被杀掉。然后同样问排在第9位的人,然后 问排在第8位的人,.…以此类推。在这其中,10个人所能做 的只有当他被魔鬼问到的时候,答白色或者黑色。不能有超 越此范围的任何行动,不然,魔鬼会把它们10个人全部杀 死。现在魔鬼给他们10个人一晚上的时间去商量一个对策,使 得他们中能存活下来的人越多越好。请问,你会有什么样的 对策,请计算出按照你的对策执行时最坏的情况下,他们中 能有多少人能100%够活下来?期望能活下来的人数又是多 少?

102. 遍历输入流,将符号和数字分开存到两个数组里,减号作为数字的负数。然后在符号集里面找*或者/,找到就把对应的数组集两个操作数比较并排序。然后数组被分割成三段,中间是乘法和两个交换数,两边是没有操作的数据,然后分别对两边做递归。如果没有找到*或者/说明全是加法,直接对数组的数据进行 排序。

103.求最长回文子串的长度

104.给定无序整数序列,求连续子串最大和。

105.给定无序整数序列,求其中第K大的数。

106.分输入是以1和0表示的一张地图,其中1代表陆地,0 代表海洋。岛屿是1上下左右相连通的区域。(不包括对角 线)输岀是岛屿的个数。可以认为地图的周围都是海洋。此题的另一个版本要求同时输岀最大区域的面积(1的个 数);输入先给岀两个整数作为数组的长和宽,各元素之间 有空格隔开。本题的输入是直接给出数组内容且元素之间没 有空格,读取输入并获得数组的维度有一定技巧。

107. C++线程同步的四种方式

108.求数组的连续最大和

109. 多态的实现原理

110. 同一个IP同一个端口可以同时建立tcp和udp的连接吗

111. 堆和栈的区别

112. 假如已知有n个人和m对好友关系(存于数字r)。如 果两个人是直接或间接的好友(好友的好友的好友…),则 认为他们属于同一个朋友圈,请写程序求岀这n个人里一共 有多少个朋友圈。

113. 请问如何保证単例模式只有唯一实例?你知道的都有哪些方法?

114. 请问数据库事物的一致性

115.请问IP地址作用,以及MAC地址作用

116.超时重传机制

117. mysql分库分表

118. 我们在将某个订单送给某一司机之前,需要计算一下这 个司机选择接受这个订单的概率,现有A,B两个订单,对某 一司机。已知;

119. 2015盏灯,一开始全部熄灭,序号分别是1-2015,先把 1的倍数序号的灯的开关全部按一次,然后把2的倍数的灯 的开关全部按一次,然后把3的倍数的开关按一次,以此类 推,最后把2015的倍数灯的开关按一次。问最后亮着的灯 有多少盏?

120.排序算法系列之算法性能评价标准与算法选择标准


101. 分现在有10个人被一个魔鬼逮住了。魔鬼对于直接把人 杀掉的方法不感兴趣了。于是,他就想了一个杀人的新花样。 是这样的,一天晚上,魔鬼向着十个人宣布了游戏规则,即 明天早上他要把10个人排成一排,然后从一堆既有无限多 的白帽子混着无限多黑帽子的帽子堆为每个人随机抽取一 顶帽子,给他们10个人都戴上帽子。因为10个人是排成一 排的,所以排在第10个的人可以看到前面9个人帽子的颜 色,排在第9个人可以看到前面8个人的帽子的颜色,…以 此类推。然后,魔鬼会从排在第10个人开始,问他,你头 上的帽子的颜色是白色还是黑色,如果答对了,就放他走; 如果答错了,就被杀掉。然后同样问排在第9位的人,然后 问排在第8位的人,.…以此类推。在这其中,10个人所能做 的只有当他被魔鬼问到的时候,答白色或者黑色。不能有超 越此范围的任何行动,不然,魔鬼会把它们10个人全部杀 死。
现在魔鬼给他们10个人一晚上的时间去商量一个对策,使 得他们中能存活下来的人越多越好。请问,你会有什么样的 对策,请计算出按照你的对策执行时最坏的情况下,他们中 能有多少人能100%够活下来?期望能活下来的人数又是多 少?

大家约定白代表偶,黑代表奇,则第10个人的回答是前9个帽子中白帽的数量的奇偶。 他自己有50%的机会。-第9个人听到他的回答后,结合他看到的8顶帽子中白帽的奇 偶,可以知道自己的帽子的颜色,如实作答。第8个人知道9顶帽子中白帽的奇偶,加 上听到第9顶帽子的颜-色,就可以知道前8顶帽子中白帽的奇偶(如果第9个人答白, 则前8顶中的白帽奇偶性与第第10个人所说的相反;如果第9个人答黑,则相同),再 结合所看到前7顶-帽子中的白帽数量,也可以推出自己的帽子颜色,也如实作答。依 此类推,前9个人都可以活下来,第1个人有一半机会。


102. 遍历输入流,将符号和数字分开存到两个数组里,减号作为数字的负数。然后在符号集里面找*或者/,找到就把对应的数组集两个操作数比较并排序。
然后数组被分割成三段,中间是乘法和两个交换数,两边是没有操作的数据,然后分别对两边做递归。
如果没有找到*或者/说明全是加法,直接对数组的数据进行 排序。

#include <iostrearn〉
#include 〈vector〉
#include〈math. h>
using namespace std;
/林
1 + 2 + 1+-4 *-5 + 1
1 + 1 + 2 +-5 *-4 + 1
*/
int data[100];
char fuhao L100J;
/林
*快排序
* ©param a
* ©param low
* ©param high
*/
void quicksort (int af], int low , in,: high)
if (low<high)
[
int i = low, j = high;
int x = a[low];
while(i〈j)
[
while(i<j && a[j] >= x) j—; if(i<j) a[i++] = a[j];
while(i<j && a[i] <= x) i++; if(i<j) a[j—] = a[i];
a[i] = x;
quicksort (a, low , i-l); quicksort (a, i+1 , high);
void my Sort (int data[], char fuhao int begin, int end) { for (int i = begin; i < end; ++^) {
if (fuhao [i] == W | | fuhao [i] == ' /') {
//先对乘除两边进行排序
if (data[i] > data[i+1];{
int temp = data[i];
data[i] = data[i+1].
data[i+1] = temp;
my Sort (data, fuhao, begin, i-l); my Sort (data: fuhao, i+2, end); return;
//没有乘除号,就对-的数字进行排序 quicksort (data, begin, end);
int main。{
int n = -1;
char temp;
int size__data = 0;
int size__fuhao - 0;
getchax ();
scanf("%c”, &temp);
int num - 0; bool munes = false;
while (temp != 9 \n ){
if (temp == ' +' I I temp //添加数字 if (munes){
=* || g =='/'){
num = "num;
data [size__data++] num = 0;
munes - false;
num
//添加符号
fuhao[s i z e_fuhao++]
else if (temp >= ‘0’ &&
num - num*10 + temp - ‘0’ ; } else if (temp == ',) {
//谒见负号
munes = true
temp <= ‘96
temp;
scanf(”%c”, &temp);
data[size__data++] - num;
my Sort (data, fuhao, 0, size_data"l);
for (int i = 0; printf ("%d”, data[i]); printf (°%cfuhao [i]);
i < size_data - 1; ++i) {
cout<< data[size_data"l]; return 0;

103.求最长回文子串的长度

#include <string・ h>
#include <iostream>
#include 〈algorithm〉
using namespace std;
int get_longest_palindromic(string s) {
int len = s. size ();
s. resize (2 * len + 1); // 重S string 的长度
for (int i = 2 * len; i >= 0; i—) {
if (i % 2 == 0)s[i]=,.;
else s[i] = s[i / 2];
}
len = s. size ();
int mv = 1;
for (int i = 0; i < len; i++){
int 1 = i - 1, r = i + 1;
int ent = 1;
while(1 >= 0 && r <= len){
if (s[l—] == s [r++]) ent X 2;
else break;
}
mv = max (mv, ent);
}
return mv » 1; // 要除 2
}
int main() {
string s;
string end = 〃END";
int len = s. size ();
int num - 1;
while(cin >> s && s・compare(end;) {
cout « "Case " « num++ « << get_longest_palindromic(s) « endl;
}
return 0;
1

104.给定无序整数序列,求连续子串最大和。

package coding;
import java. util. *;
public class Main {
public static void main(String[. args) {
Scanner in = new Scanner(System, in);
String nextLine = in. nextLine();
String[] splits = nextLine. split
ArrayList<Integer> A = new ArrayList<Integer> (); for (int i = 0; i < splits.length; i++) {
A. add(integer, parselnt (splits[i]));
if(A==nullI I A. size()==0) return ;
ArrayList<Integer> result = new ArrayList<Integer> (); result, add(-l);
result, add(-l);
int min = 0;
int max = Integer. MIN_VALUE;
int minpos = ~1;
int sum = 0;
for(int i = 0;i<A.size();i-+) (
sum += A. get (i);
if(sum - min > max){
result, set(0 , minpos);
max = sum - min;
result.set (1 , i);
}
if(sum < min){
min = sum;
minpos = i;
}
}
int temp = result, get(0);
result, set(0 , temp + 1);
int re - 0;
for(int i = result, get(0); i <= result.get(1); i ++){ re x A. get(i);
System, out. printIn(max);

105.给定无序整数序列,求其中第K大的数。

package cn. thinkingl?;
import java. io. *;
import java. util. *;
public class NOK {
public static void main(String args[])
{
Scanner in = new Scanner(System, in);
String nextLine = in. nextLine();
int kth = in. nextlnt ();
String[] splits = nextLine. split“); int[] numbers = new int [splits, length];
for (int i = 0; i < numbers, length; i++) { numbers[i] = Integer.parselnt(splits[i]);
System, out. printIn(kthLargestElement (2, numbers));
public static int kthLargestElenent(int k, int[] nums) { if (nums == null || nums.length == 0) {
return 0;
if (k <= 0){
return 0;
return helper (nums, 0, nums. length - 1, nums. length ~ k + 1);
}
public static int helper(int[] nums, int L int r, int k) { if (1 == r) {
return nums[1];
}
int position = partition(nuns, 1, r);
i£ (position +1 -- k) {
return nums[position];
} else if (position + 1 < k; {
return helper(nums, position + 1, r, k);
} else {
return helper(nums, L position - L k);
public static int partitiontint.] nums, int 1, int r) { int left = 1, right = r;
int pivot = nums[left];
while (left < right) {
while (left < right && nums[right] >= pivot) {
right—;
I
nums[left] = nums[right.;
while (left < right && nums[left] <= pivot) {
left++;
}
nums[right] = nums[left.;
}
nums[left] = pivot;
return left;
}
}

106.分输入是以1和0表示的一张地图,其中1代表陆地,0 代表海洋。岛屿是1上下左右相连通的区域。(不包括对角 线)输岀是岛屿的个数。可以认为地图的周围都是海洋。
此题的另一个版本要求同时输岀最大区域的面积(1的个 数);输入先给岀两个整数作为数组的长和宽,各元素之间 有空格隔开。本题的输入是直接给出数组内容且元素之间没 有空格,读取输入并获得数组的维度有一定技巧。

#include <cstdio>
#include "string,
using namespace std;
typedef struct node{
bool island;
} Node;
int row = 0, col = 0;
Node map[1000][1000];
void mark_area(int i, int j){ /*右隽的节点*/ if(j+1 < col && map[i][j+1].island){ map[i][j+1]. island = false; mark^areatij j+1);
}
/*下方的节点*/
if(i+1 < row && map[i+1][j]. island){
map[i+1][j]. island = false; mark_area (i+L j);
}
/*左方的节点*/
if (j~l >=0 && map[i][j-1].island){
map[i][j~l]. island = false; mark^areatij j~l);
}
/*上方的节点*/
if (i-1 >=0 && map[i-l] [j]. island) {
mapfi"l] [j].island = false; mark_area(i~l, j);
}
return;
}
int main(int argc, char **argv){
/*数组清零*/
memset(map, 0, sizeof(Node) * le6);
A输入读耿+/
char n;
int i = 0, j = 0;
while(true){
if (scanf (”%c”, &n) == EOF) {
row = i + 1;
goto JtlARK;
else if (n == ' \n‘ | | n == ' \rJ) {
i++;
col = j;
j = 0;
}
else{
map [i] [ j ]. island = (bool) (n - J 0J);
I
} // end of while loop
MARK:
/*打印内容*/
printf ("row = %d, col = %d\n°J tow, col);
for(i = 0; i < row; i++) {
for (j = 0; j < col ;j++){ printf(°%d map [i] [j]. island);
}
printf("\nO;
}
/*计算岛屿数*/
int groups = 0;
ford = 0; i < row; i++) {
for(j = 0; j < col ;j++){
if (map [i] [ j]. island == ■:rue) {
groups
map[i] [j].island = false; jnark_area(i, j);
printf(〃%d\n“3 groups); return 0;

107. C++线程同步的四种方式

(1) 事件(Event);
(2) 信号量(semaphore);
(3) 互斥量(mutex);
(4) 临界区(Critical section);

1. 事件
事件(Event)是WIN32提供的最灵活的线程间同步方式,事件可以处于激发状态

(signaled or hue)或未激发状态(unsignal or false) o根据状态变迁方式的不同, 事件可分为两类:
(1) 手动设置:这种对象只可能用程序手动设置,在需要该事件或者事件发生时,采 用SetEvent及ResetEvent来进行设置。
(2) 自动恢复:一旦事件发生并被处理后,自动恢复到没有事件状态,不需要再次设 置。
使用”事件”机制应注意以下事项:
(1) 如果跨进程访问事件,必须对事件命名,在对事件命名的时候,要注意不要与系 统命名空间中的其它全局命名对象冲突;
(2) 事件是否要自动恢复;
(3) 事件的初始状态设置。
由于event对象属于内核对象,故进程B可以调用OpenEvent函数通过对象的名字获得 进程A中event对象的句柄,然后将这个句柄用于ResetEvent x SetEvent和 WaitForMultipleObjects等函数中。此法可以实现一个进程的线程控制另一进程中线 程的运行,例如:

•include "stdafx. h"
^include〈windows. h>
#include<i ostream,
using namespace std;
int number = 1; 〃定义全局変里
HANDLE hEvent; //定义事件句柄
unsigned long   stdcall ThreadProcl (void* Ip)
[
while (number < 100)
[
Wai tForSingleObj ect (hEvent, INFINITE); 〃等待对象为有信号状态
cout « "thread 1 : ^«nwnber « endl;
++number:
.sleep (100);
SetEvent (hEvent):
}
return 0:
}
unsigned long   stdcall ThreadProc2 (void* Ip)
I
while (number < 100)
I
Kai tForSingleObj ect (hEvent, INFINITE); 〃等待对象为有信号状态
cout « "thread 2 : ^«nwnber « endl;
++nwnber;
_sleep (100):
SetEvent (hEvent);
}
return 0;
}
int main()
I
Great eThread (NULL, 0, ThreadProcl, NULL, 0, NULL);
Great eThread (NULL, 0, ThreadProc2, NULL, 0, NULL);
hEvent = GreateEvent(NULL, FALSE, TRUE, "event");
Sleep (10*1000):
system("pause"):
return 0;
I

2. 信号量
信号量是维护。到指定最大值之间的同步对象。信号量状态在其计数大于。时是有信号 的,而其计数是。时是无信号的。信号量対象在控制上可以支持有限数量共享资源的访 问。
信号量的特点和用途可用下列几句话定义:
(1)如果当前资源的数量大于。,则信号量有效;
(2 )如果当前资源数量是0,则信号量无效:
(3) 系统决不允许当前资源的数量为负值;
(4) 当前资源数量决不能大于最大资源数量。

Sinclude "stdafx. h"
^include〈windows. h>
#i nclude <i ostreajnz,
using namespace std;
int number = 1; //定义全局艾里
HANDLE hSemaphore; //定义信号里句柄
unsigned long   stdcall ThreadProcl (void* Ip)
I
long count;
while (number < 100)
I
〃等待信号里为有信号状态
Wai tForSingleObj ect (hSemaphore, INFINITE):
cout « "thread 1 : ^«nwnber « endl;
++nwnber:
.sleep (100);
ReleaseSemaphore (hSemaphore, Scount):
}
return 0;
}
unsigned long   stdcall ThreadProc2 (void* Ip)
[
long count:
while (number < 100)
[
〃等待信号里为有信号状态
Wai tForSingleObj ect (hSemaphore, INFINITE):
cout « "thread 2 : ^«nwnber « endl;
,Unwnber:
.sleep (100);
ReleaseSemaphore (hSemaphore, ftcount):
I
return 0:
I
int main()
[
hSemaphore = Cr e at eS em aphor e (HULL, 1? 100? “sema"):
CreateThreadQTULL, 0, ThreadProcl, NULL, 0, HULL);
CreateThreadQlULL, 0, ThreadProc2, NULL, 0, HULL):
Sleep (10*1000):
system ("pause"):
return 0;
I

土互反星.
采用互反对象机制。只有拥有互乓对象的线程才有访问公共资源的权限,因为互斤对 象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一 应用程序的公共资源安全共享, 还能实现不同应用程序的公共资源安全共享。

•include "stdafx. h"
^include〈windows. h>
#include<i ostreajnz,
using namespace std;   int number = 1; 〃定义全局変里
HANDLE hNutex; //定义互斥对象句柄
unsigned long   stdcall ThreadProcl (void* lp)
I
while (number < 100)
I
WaitForSingleObject (Mbitex, INFINITE);
cout « "thread 1 : "«number « endl;
++nwnber;
.sleep (100):
ReleaseMutex(Wdutex):
I
return 0;
I
unsigned long   stdcall ThreadProc2 (void* lp)
[
while (number < 100)
[
WaitForSingleObject (Mbitex, INFINITE):
cout « "thread 2 : "«number « endl;
++nwnber:
.sleep (100):
ReleaseMutex(Wdutex):
I
return 0;
I
int main。
{
Wdutex = Great eMutex (NULL, false, "mutex") : //创建互斥对象
Cr eat eThread (NULL, 0, ThreadProcl, NULL, 0, NULL);
Great eThread (NULL, 0, ThreadProc2, NULL, 0, NULL);
Sleep (10*1000);
system ("pause");
return 0;
}

4. 临界区
临界区(Critical Section)是一段独占对某些共享资源访问的代码,在任意时刻只允 许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个 线程进入后其他所有试图访问此临界区的线程将被挂起并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享 资源的目的。
临界区在使用时以CRITICAL_SECTICN结构对象保护共享箜源,并分别用 EnterCriticalSection ()和 LeaveCriticalSection ()函数去标识和释放一个临界 区。所用到的 CRITICAL_SECTION 结构对象必须经过 InitializeCriticalSection () 的初始化后才能使用,而且必须确保所有銭程中的任何试图访问此共享资源的代码都处 在此临界区的保护之下。否则临界区将不会起到应有的作用,共享资源依然有被破坏的 可能。

•include "stdafx. h"
^include〈windows. h>
#include<i ostream,
using namespace std;
int number = 1; //定义全局変里
CRITICAL.SECTION Critical; //定义临界区句柄
unsigned long   stdcall ThreadProcl (void* lp)
[
while (number < 100)
[
EnterCri ticalSection(&Cri tied.);
cout « "thread 1 : ^«nwnber « endl;
,Unwnber:
.sleep (100);
LeaveCri ti calSecti on (SCri ti csl):
I
return 0:
}
unsigned long   stdcall ThreadProc2 (void* lp)
{
while (number < 100)
{
EnterCriticalSection(ACriticsl):
cout « "thread 2 : ^«nwnber « endl;
++nwnber:
.sleep (100);
LeaveCri ti calSecti on (&Cri ti c£L):
}
return 0;
int main()
I
Ini ti ali zeCri ti calSecti on (&Cri ti cal) : //初始化临界区对象
Great eThread (NULL, 0, ThreadProcl, NULL, 0, NULL);
Great eThread (NULL, 0, ThreadProc2, NULL, 0, NULL);
Sleep (10*1000);
system ("pause"):
return 0:
}

108.求数组的连续最大和

#include <bits/stdc++. h>
using namespace std;
typedef long long LL;
int main()
[
int n;
while (cin >> n) {
vector<int> arr;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
arr.push_back(x);
}
vector<LL> dp(n, 0);
LL ans = arr[0];
dp[O] = arr [0];
for (int i = 1; i < n; i++) {
dp[i] = dp[i - 1] < 0 ? arr[i] : dp[i - 1] + arr[i]; ans - max (dp Til, ans);
cout << ans << endl;
return 0;

109. 多态的实现原理

1. 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。
2. 存在虚函数的类都有一个一维的虚函数表叫做虚表。当类中声明虚函数时,编译器 会在类中生成一个虚函数表。
3. 类的对象有一个指向虚表开始的虚指外。虚表是和类对应的,虚表指针是和对象对 应的。
4. 虚函数表是一个存储类成员函数指针的数据结构。
5. 虚函数表是由编译器自动生成与维护的。
6. virtual成员函数会被编译器放入虚函数表中。
7. 当存在虚函数时,每个对象中都有一个指向虚函数的指针(CH编译器给父类对象, 子类对象提前布局vptr指针),当进行test (parent *base)函数的时候,C++编译器 不需要区分子类或者父类对象,只需要再base指针中,找到vptr指针即可)。
8. vptr-般作为类对象的第一个成员。


110. 同一个IP同一个端口可以同时建立tcp和udp的连接吗

可以,同一个端口虽然udp和tcp的端口数字是一样的,但实质他们是不同的端口,所 以是没有影响的,从底层实质分析,对于每一个连接内核维护了一个五元组,包含了源 ip,目的ip、源端口目的端口、以及传输协议,在这里尽管前4项都一样,但是传输 协议是不一样的,所以内核会认为是2个不同的连接,在ip层就会进行开始分流,tcp 的走 tcp, udp 走 udp。


111. 堆和栈的区别

1. 从管理方式上,
栈是由编译器自动管理,无需我们手动控制;
对于堆,开辟和释放工作由程序员控制,所以有内存泄漏等情况的发生。
2. 从申请大小上,
栈是有高地址向低地址扩展的,是一块连续的内存区域,所以栈的栈顶地址或者大小是 —开始就分配好的。在使用过程中,比如递归调用层数过多,那么就有可能造成栈溢出, 所以栈能获得的空间比较少;
堆是向高地址扩展的,是链表组织的方式,所以有可能是不连续的,他的大小只受限于 有效的虚拟内存大小,所以堆能幵辟的空间较大。
3. 从碎片问题上,
栈是没有碎片的情况,因为他有严格的出H入栈,不会存在一个内存块从栈的中间位置 弹出;
堆有碎片的情况,频繁的调用new/delete分配释放内存,必然会造成内存碎片。
4. 从分配方式上,
堆都是动态分配的
栈大多是静态分配的,也可以动态分配,可以由alloc©数分配。
5. 从分配效率上,
计算机会在底层对栈提供支持,比如有专门的寄存器分配,用来存放栈的地址,压栈出 栈的指令等;


112. 假如已知有n个人和m对好友关系(存于数字r)。如 果两个人是直接或间接的好友(好友的好友的好友…),则 认为他们属于同一个朋友圈,请写程序求岀这n个人里一共 有多少个朋友圈。

假如:n = 5 , m = 3 , r = {{1,2}, {2,3}, {4,5}},表示有 5 个人,1和2是好友,2和3是好友,4和5是好友,则1、 2、3属于一个朋友圈,4、5属于另一个朋友圈,结果为2 个朋友圈。
#include <stdio.h>
int set [10] = {0};
int find (int a)
[
int r, i, j;
r = a;
while (r != set[r])
r = set[r];
i = a;
while(i J= r)
[
j = set[i];
set[i] = r;
i = j;
I
return r;
void merge (int a, int b)
[
int a_father = find(a);
int b_father = find(b);
if(a_father == b_father)
return;
else if(a_father < b_father)
set[b_father] = a_father;
else
set[a_father] = b_father;
int friends (int n, int m, int r [] [2.)
[
int i, count=0;
for(i=0;i<n;i++)
set[i] = i;
for(i=0;i<m;i++)
merge(r[i] [0],r[i] [1]);
for(i=0;i<n;i++)
if(set [i] == i)
count++;
return count;
int main()
[
int n=5, m=3, count=0, i;
int r[3] [2] = {{1,2}, {2,3}, {4, 5]};
printf ("朋友圈关系:\n");
for(i=0;i<3;i++)
printf r [i] [0], r [J [1]);
printf (侦);
count = friends (n, m, r);
printf ("朋友圈个数为:\n%d\n,z, count);
return 0;
}

113. 请问如何保证単例模式只有唯一实例?你知道的都有哪些方法?

单例的实现主要是通过以下两个步骤:
将该类的构造方法定义为私有方法,这样其他处的代码就无法通过调用该类的构造方法 来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例;
在该类内提供一个静态方法,当我们调用玄个方法时,如果类持有的引用不为空就返回 这个引用,如果类保持的引用为空就创建:•亥类的实例并将实例的引用赋予该类保持的引 用。
单例模式的实现主要有两种一种是欲汉式,一种是懒汉式。欲汉式线程安全的单例模式 如下:

public class Singleton (
private final static Singleton INSTANCE ■ new Singleton();
private Singleton()(}
public static Singleton getlnstance()(
return INSTANCE;

懒汉式线程安全的单例模式如下

public class Singleton (
private static volatile Singleton singleton;
private Singleton()()
public static Singleton getlnstance () ( if (singleton == null) {
synchronized (Singleton.class) { if (singleton == null)( singleton = new Singleton();
return singleton;

114. 请问数据库事物的一致性

事务(Transaction)是由一系列对系统中数据进行访问与更新的操作所组成的一个程 序执行逻辑单元。事务是DBMS中最基础的单位,事务不可分割。
事务具有4个基本特征,分别是:原子性(Atomicity)、一致性(Consistency)、隔 离性(Isolation)、持久性(Duration) > 简称ACID。

1) 原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务 的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影 响。

2) —致性(Consistency)
—致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一 个事务执行之前和执行之后都必须处于一致性状态。篁转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间 如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事 务的「致性。

3) 隔离性(Isolation)
隔离性是当多个用户并发访问数据摩时,比如操作同一张表时,数据库为每一个用户开 启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么 在T1开始之前就已经结束,要么在T1结束之后才幵始,这样每个事务都感觉不到有其 他事务在并发地执行。
多个事务并发访问时,事务之间是隔离依,一个事务不应该影响其它事务运行效果。这 指的是在并发环境中,当不同的事务同日由集纵相同的数据时,每个事务都有各自的完整 数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。

不同的隔离级别:
Read Uncommitted (读职未提交[添加中文释义]内容):最低的隔离级别,什么都不需 要做,一个事务可以读到另一个事务未提交的结果。所有的并发事务问题都会发生。
Read Committed (读取提交内容):只有在事务提交后,其更新结果才会被其他事务看 见。可以解决脏读问题。
Repeated Read (可重复读):在一个事务中,对于同一份数据的读取结果总是相同的, 无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。可以解决脏读、不 可重复读。
Serialization (可串行化):事务串行亿执行,隔离级别最高,牺牲了系统的并发性。 可以解决并发事务的所有问题。

4) 持久性(Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便 是在数据库系统谒到故障的情况下也不会丢失提交事务的操作。
例如我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当 我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库 出现了问题,也必须要将我们的事务完全丸行完成,否则就会造成我们看到提示事务处 理完毕,但是数据库因为故障而没有执行事务的重大错误。


115.请问IP地址作用,以及MAC地址作用

曲c地址是一个硬件地址,用来定义网絡设备的位置,主要由数据链路层负责。而ip 地址是ip协议提供的一种统一的地址格弍,为互联网上的每一个网络和每一台主机分 配一个逻辑地址,以此来屏蔽物理地址的差异。


116.超时重传机制

超时重传是TCP保证数据传输可靠性的又一大措施,本文主要介绍重传TCP报文的两大举措:超时重传和快速重传

超时重传机制

超时重传指的是,发送数据包在一定的时间周期内没有收到相应的ACK,等待一定的时 间,超时之后就认为这个数据包丢失,就会重新发送。这个等待时间被称为Rm.

检测丢失segment的方法从概念上讲还是比较简单的,每一次开始发送一个TCP segment的时候,就启动重传定时器,定时器的时间一开始是一个预设的值(Linux规 定为姑),随着通讯的变化以及时间的推移,这个定时器的溢出值是不断的在变化的, 有相关算法计算RTO [参考:文章如果在ACK收到之前,定时器到期,协议栈就 会认为这个片段被丢失,重新传送数据。

TCP在实现重传机制的时候,需要保证能够在同一时刻有效的处理多个没有被确认的 ACK,也保证在合适的时候对每一个片段进行重传,有这样几点原则:

1. 这些被发送的片段放在一个窗口中,等待被确认,没有确认不会从窗口中移走,定 时器在重传时间到期内,每个片段的位置不变,这个地方其实在滑动窗口的时候也有提 到过

2 .只有等到ACK收到的时候,变成发送并ACK的片段,才会被从窗口中移走。

3 .如果定时器到期没有收到对应ACK,就重传这个TCP segment

重传之后也没有办法完全保证,数据段一定被收到,所以仍然会重置定时器,等待ACK, 如果定时器到期还是没有收到ACK,继续重传,这个过程重传的TCP segment -直留着 队列之内。

举个重传的例子:

1. Server 发送80 个字节 Parti, seq = 1
2. Server 发送 120 个字节 Part2, Seq - 81
3. Server发送160个字节Part3, Seq = 201,此包由于其他原因丢失
4. Client收到前2个报文段,并发送ACK = 201
5. Server 发送 140 个字节 Part4, Seq = 361
7. Server收到Client对于前两个报文段的ACK,将2个报文从窗口中移除,窗口有
2。。个字节的余量
8. 报文3的重传定时器到期,没有收到ACK,进行重传
9. 这个时候Client已经收到报文4,存放在緩冲区中,也不会发送ACK [累计通知, 发送ACK就表示3也收到了】,等待报文3,报文3收到之后,一块对3,4进行确认
10. Server收到确认之后,将报文3,4移除窗口,所有数据发送完成
总结就是2中处理
1. 定时器溢出,重传3
2. 定时器溢出,重传3,4

117. mysql分库分表

mysql分库分表: 场景:在进行设计数据库时,在用户量不大的情况下单表单库在承载最大2000/s以下 的请求应该是没有问题的,单表磁盘存儲200w已经就够多了。但是如果单表单库的情 况下达到这么高的并发和存储对mysql数据库的性能有极大的挑战。当业务发展变大可 以进行redis緩存解决一部分查请求并发减少mysql压力值,达到mysql阚值可以使用 MQ进行削峰,但是这个不是长久的办法,如果业务量再次加大那么前面的措施会极大 的影响程序性能。

mysql的分库分表用于在高并发大业务量的情况下的mysql性能优化。

分库:在原本的但库的情况下最大能承载的并发量也就2000/sQPS,万一 QPS直接到lw 及以上就算使用胸也会堆积大量数据请求需要处理,这个时候就可以进行数据库分库, 单摩时2000/sQPS那么来5个库就是最高1破PS承载量

分表:大量的写操作在单表的情况下很容易堆积大量数据假设单表存储600w数据, 整个查询的速率都会下降,整个性能都会下降。怎么办?分表。把这么大的表进行拆分, 拆分可以用垂直和水平拆分。垂直拆分就是把一个表的字段往小了拆,把查询高频字段 保留低频拆成一个表,需要低频数据直接緩存篁。水平拆分就是把表砍成几段,也就是 这样的分表是在表结构一样的前提下分表,按照表的唯一id进行划分

分库分表场景:例如在大型互联网公司有上亿的用户,这么高并发大数据的进行对数据 库的操作需要进行分库分表,首先假设现在已有Iw/sQPS进行分库分5个库,一张表 1000w数据,先进行每个库的分表水平分5个表给每个库,在每个摩里面在水平分4个 表也就是现在每个表才50w数据,怎么分呢,可以用hash,也可以用range,用hash 就直接hash路由id到对应的库的对应的表,也就是现在有5个库20张表,hash路由 先%5找库,在%20找表

分库分表问题:

1. 如果之前进行架构时是单表单摩但是因为业务量増加需要分库分表怎么办?

① 停机维护,及其不建议(这个停机肯定至要在没人的时候也就是凌晨开始加班到第二 天早上,不好不好对身体不好)。首先写个后台程序去吧数据库数据全部读出来,按照 分库分表的架构把摩和表搭起来,然后把全部的数据按照hash或者range的方式进行 数据划分,如果按照hash路由,就直接程序跑起来id取模找对应的库和表存储。这个 方法不仅伤身体还费力,如果在早上5前这个数据还没分完那就没办法了直接按照原先 的单摩单表运行然后在等下一个天亮。

② 不停机维护,双写迁移。什么叫双写,就是在不影响用户的情况下进行分库分表操作。 怎么操作,首先一样的先把库和表结构搭出来,然后在系统后台开一个程序进行迁移, 在用户进行读写操作时,往旧库操作同时向新库操作。后台程序和用户读写同时进行操 作新摩,为了数据一致性在进行操作时激进型判断,这条数据是否存在不存在就插入存 在就看最后的修改时间按照最新的修改旺间数据进行存储


118. 我们在将某个订单送给某一司机之前,需要计算一下这 个司机选择接受这个订单的概率,现有A,B两个订单,对某 一司机。已知;

1. 如果只将订单A播送给司机,司机接受的概率是Pa;

2. 如果只将订单B播送给司机,司机接受的概率是Pb;

[1-(l-Pa)*(1-Pb)]*P a/(Pa+Pb)

(l-pa)*(l-pb)是两个单都不接的概率,l-(l-pa)*(l-pb)是接单的概率Pa/(Pa+Pb)是 在两者中选择Pa的概率


119. 2015盏灯,一开始全部熄灭,序号分别是1-2015,先把 1的倍数序号的灯的开关全部按一次,然后把2的倍数的灯 的开关全部按一次,然后把3的倍数的开关按一次,以此类 推,最后把2015的倍数灯的开关按一次。问最后亮着的灯 有多少盏?

答案是44

思路:某灯亮着f该灯被按了单数次f该灯有单数个正约数,所以找到1到2015中正 约数个数为单数的数字即可。观察发现,只有完全平方数的正约数才是单数个(若不是

完全平方数,它的任意一个约数总有另一个约数与之对应)。所以亮着的灯分别是{1 的平方,2的平方,3的平方,。。。,不大于2015的最大平方数},利用给出的选项 即可得到结果。

#include <stdio.h>
void main() {
int azrL2016j=t0}; 〃刚幵始全火
int i, j ;
int count=0;
for(i=l;i<=2015;i++){
for(j=i;j<=2015;j++){
if(j % i == 0){
axr[j] = axr[j]==O ? 1 : 0;
for(i=l;i<=2015;i++){ if (axr[i] == 1) { count++;
printfcount);

120.排序算法系列之算法性能评价标准与算法选择标准

算法的时间复杂度和空间复杂度

所谓算法的时间复杂度,是指执行算法防需要的计算工作量。

—个算法的空间复杂度,一般是指执行这个算法所需要的内存空间。

1.性能评价标准

1) 、稳定性比较

稳定度:稳定排序算法会依照相等的关键(换言之就是值)维持纪录的相对次序。也就 是一个排序算法是稳定的,就是当有两个有相等关键的纪录R和S,且在原本的串行中 R出现在S之前,在排序过的串行中R也将会是在S之前。

插入排序、冒泡排序、二叉树排序、二路归并排序及其他线形排序是稳定的. 选择排序、希尔排序、快速排序、堆排序是不稳定的.

2) 、计算的复杂度(最差、平均、和最好表现)

依据串行(list)的大小3)。一般而言,好的表现是0 (n log n),且坏的行为是0 (n2)。 对于一个排序理想的表现是0(n)。仅使用一个抽象关键比较运算的排序算法总平均上 总是至少需要。(n log n)。

平W况 最场情況
E芬排瘁 O(nlogn) Ofnlogn) O(nlogn)
基g字 O(n) 0<n) O(n)
快遑排序 OCnlogn) O(nlogn) O(n2)
藉尔排字 O(nl.5) O(n) O(nl.5)
插入排字 0(n2) 0(n) O(n2)
透择排序 0(n2) 0(n2) O(n2)

3) 、辅助空间的比较

线形排序、二路归并排序的辅助空间为。(荷,其它排序的辅助空间为。(1);

4) 、其它比较

插入、冒泡排序的速度较慢,但当参加排序的序列局部或整体有序时,这种排序能达到 较快的速度。

反而在这种情况下,快速排序反而慢了。

2. 选择标准

当n较小时,对稳定性不作要求时宜用j封荃排序,对稳定性有要求时宜用插入或冒泡排 序。

若待排序的记录的关键字在一个明显有限范围内时,且空间允许是用捅排序。

当n较大时,关键字元素比较随机,对稳定性没要求宜用快速排序。

当n较大时,关键字元素可能出现本身是有序的,对稳定性有要求时,空间允许的情况 下。

宜用归并排序。

当n较大时,关键字元素可能出现本身是有序的,对稳定性没有要求时宜用堆排序。


秋招大厂经典面试题及答案整理不断更新中,感兴趣且正在学习的同学可以点个关注;狮会不断更新文章连载,有问题或者见解可以评论区讨论。

2023秋招大厂经典面试题及答案整理归纳(101-120)校招必看相关推荐

  1. 2023秋招大厂经典面试题及答案整理归纳(1-20)校招必看

    目录 前言 1. 使用mysql索引都有哪些原则?索引什么数据结构? 1). 对于查询频率高的字段创建索引: 2). 对排序.分组.联合查询频率高的字段创建索引: 3). 索引的数目不宜太多 4). ...

  2. 2023秋招大厂经典面试题及答案整理归纳(201-220)校招必看

    目录 201.数组al[O,mid-l]和al[mid,num-l],都分别有序.将其 merge成有序数组al[O,num-1],要求空间复杂度0(1). 202. 一个url指向的页面里面有另一个 ...

  3. 2023秋招大厂经典面试题及答案整理归纳(141-160)校招必看

    目录 141. 动态连接库的两种方式? 142. IP组播有那些好处? 143. 列举几种进程的同步机制及优缺点 144. 什么是预编译,何时需要预编译? 145. int(*s[10])(int)表 ...

  4. 2023秋招大厂经典面试题及答案整理归纳(161-180)校招必看

    目录 161. MySQL 中 myisam 与 innodb 的区别. 162. 画出OSI和TCP/IP协议栈的对应关系. 163. 简述停止-等待协议(ARQ)的工作原理? 164. redis ...

  5. 【2023秋招大厂真题】携程校招-2022.9.28-k-好数组

    2023大厂真题提交网址(含题解): www.CodeFun2000.com(http://101.43.147.120/) 最近我们一直在将收集到的机试真题制作数据并搬运到自己的OJ上,供大家免费练 ...

  6. 【2023秋招大厂真题】科大讯飞校招-2022.10.14-奖品发放

    2023大厂真题提交网址(含题解): www.CodeFun2000.com(http://101.43.147.120/) 最近我们一直在将收集到的机试真题制作数据并搬运到自己的OJ上,供大家免费练 ...

  7. 【2023秋招大厂真题】华为校招-2022.10.11-字母加密

    2023大厂真题提交网址(含题解): www.CodeFun2000.com(http://101.43.147.120/) 最近我们一直在将收集到的机试真题制作数据并搬运到自己的OJ上,供大家免费练 ...

  8. 2023最新Web前端经典面试试题及答案-史上最全前端面试题(含答案)

    近期总结一一些面试题 都是企业的面试题笔记题 感觉薪资10k-15k的常见面试题 个人录制的最新Vue项目学习视频:B站 小胖梅-的个人空间_哔哩哔哩_Bilibili 红色为常见面试题 ====== ...

  9. 2022年最新互联网大厂前端面试题及答案-前端工程必备技能(持续整理更新中【关注收藏不迷路】)

    对于做前端的朋友,或者做了前端几年了,基础不好的,或者想进大厂的想了解深入,下面的知识点很多前端朋友都没有深入了解.很重要,看完有种茅塞顿开感觉,**关注+收藏哦,总有一天用的得.** 涉及到知识点: ...

  10. 大疆秋招IBG后端笔试题 2023

    大疆秋招IBG后端笔试题 2023 题型 编程 计算时间差(Leetcode359) 最小偏移量(Leetcode1657) 题型 单选:20道:(不可修改答案好像,我没找到返回上一题的界面) 多选: ...

最新文章

  1. 即时通讯有标准 IM的四种即时通讯协议简介
  2. python3.7 6如何安装-centos安装python3.7
  3. eclipse build workspace太慢或者 js出错问题解决
  4. 虚拟机Virtualbox中的Ubuntu系统,安装增强功能时报错:未能加载虚拟光驱VBoxsGuestAdditions.iso到虚拟电脑
  5. 工厂模式(简单工厂、工厂方法、抽象工厂)
  6. Closure--1
  7. 2010计算机知识点总结,2010年全国职称计算机考试:知识点笔记第一章
  8. chiinv函数java_Excel统计函数:CHIINV函数实例-excel技巧-电脑技巧收藏家
  9. PHP面向对象6之工具-魔术方法
  10. 深入理解Yii2.0 (3)行为(Behavior)
  11. SQL Server 用SSMS查看依赖关系有时候不准确,改用代码查
  12. [简短问答]如何用虚拟打印机测试,虚拟打印机相关
  13. AutoCAD2010 激活不了,老是激活错误(0015.111)
  14. 原来win7专业版64位 MBR方式安装win10专业版_x86
  15. MariaDB数据存储引擎的选择
  16. linux 嗅探器源码,一个简易网络嗅探器的实现
  17. FastReport开发指南
  18. matlab 利用polyfitpolyval函数进行基线矫正【matlab程序】
  19. 如何从程序员升级到架构师?
  20. 网易向员工致歉|网易暴力裁员事件:希望网易不要挣了钱,凉了人

热门文章

  1. 什么是CSR证书申请文件?
  2. 用maven-replacer插件选择正则表达式替换
  3. 聊天程序设计实验报告——java
  4. 农夫山泉2面面试经历
  5. 七日杀 服务器不显示,七日杀进服务器不显示画面 | 手游网游页游攻略大全
  6. 51小项目——使用proteus搭建简易的光照度计-(1)
  7. EasyBoot制作启动光盘教程
  8. CIE 国际照明委员会
  9. Jupyter Notebook又一懒人神器,拖拽生成Python代码
  10. 绝对值对应c语言表达式,c语言绝对值函数?