1效扫、給一個(gè)由0和1組成的二維數(shù)組,1代表陸地直砂,0代表海洋菌仁,統(tǒng)計(jì)出這個(gè)二維數(shù)組中有多少塊陸地,上下左右可以連接的陸地算一塊陸地静暂。
比如下面的這個(gè)數(shù)組就有3塊陸地
0 0 0 0 1 0
0 1 0 0 0 0
1 1 1 0 0 0
0 1 0 1 0 0
這道題是leetcode題庫(kù)中的第200題济丘,一看就知道要使用圖的遍歷算法,然而圖已經(jīng)忘得一干二凈了,直接和面試官說(shuō)不會(huì)摹迷。這道題的官方解答在這:https://leetcode-cn.com/problems/number-of-islands/solution/dao-yu-shu-liang-by-leetcode/
2疟赊、有N個(gè)人從1開始編號(hào),從1開始報(bào)數(shù)峡碉,報(bào)數(shù)為M的那個(gè)人退出近哟,然后從下個(gè)人開始繼續(xù)從1開始報(bào)數(shù),請(qǐng)問(wèn)最后一個(gè)人的序號(hào)
這里提供一種解法:
public static int test1(){
List<Integer> list = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
list.add(i);
}
int m = 3;
int index = 0;
while (list.size()>1){
index += m-1;
index = index%list.size();
list.remove(index);
}
return list.get(0);
}
創(chuàng)建一個(gè)ArrayList存儲(chǔ)元素鲫寄,index指的是將要?jiǎng)h除的元素吉执,由于index可能超出list的長(zhǎng)度,所以需要和list.size()進(jìn)行模運(yùn)算地来,讓index的值始終小于list.size()/
3戳玫、大數(shù)據(jù)量分頁(yè)查詢的優(yōu)化
SELECT * FROM student LIMIT 80000,10
單純使用limit語(yǔ)句進(jìn)行分頁(yè)查詢的話實(shí)際上把所有的數(shù)據(jù)都查出來(lái)了,然后把前面的數(shù)據(jù)丟棄未斑,十分影響效率咕宿。如果主鍵id是自增的話可以考慮使用索引覆蓋。
我們都知道蜡秽,利用了索引查詢的語(yǔ)句中如果只包含了那個(gè)索引列(覆蓋索引)荠列,那么這種情況會(huì)查詢很快。
因?yàn)槔盟饕檎矣袃?yōu)化算法载城,且數(shù)據(jù)就在查詢索引上面肌似,不用再去找相關(guān)的數(shù)據(jù)地址了,這樣節(jié)省了很多時(shí)間诉瓦。另外Mysql中也有相關(guān)的索引緩存川队,在并發(fā)高的時(shí)候利用緩存就效果更好了。
SELECT * FROM student WHERE id >= (SELECT id FROM student LIMIT 80000,1) LIMIT 10
主鍵索引是聚簇索引睬澡,數(shù)據(jù)存放在節(jié)點(diǎn)上固额,所以可以通過(guò)id很快地查詢到所有列。
4煞聪、線程的三種實(shí)現(xiàn)方式以及它們的區(qū)別
第一種方式:繼承Thread類
package com.qianfeng.thread;
public class Test1 {
public static void main(String[] args) {
Thread t1 = new MyThread();
Thread t2 = new MyThread();
t1.start();
t2.start();
}
}
class MyThread extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"啟動(dòng)了");
}
}
第二種方式:實(shí)現(xiàn)Runable接口
package com.qianfeng.thread;
public class Test2 {
public static void main(String[] args) {
Thread t1 = new Thread(new MyThread2());
Thread t2 = new Thread(new MyThread2());
t1.start();
t2.start();
}
}
class MyThread2 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"啟動(dòng)了");
}
}
第三種方式:實(shí)現(xiàn)Callable接口
package com.qianfeng.thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Test3 {
public static void main(String[] args) {
MyThread3 thread = new MyThread3();
FutureTask<Integer> futureTask = new FutureTask<>(thread);
new Thread(futureTask).start();
try {
System.out.println("子線程的返回值"+futureTask.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
class MyThread3 implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName()+"啟動(dòng)了");
return 1;
}
}
對(duì)比:
- 繼承Thread類的方式比較簡(jiǎn)單斗躏,直接創(chuàng)建一個(gè)子類對(duì)象然后start。實(shí)現(xiàn)Runable接口的方法需要?jiǎng)?chuàng)建一個(gè)實(shí)現(xiàn)類的對(duì)象然后放在Thread類的構(gòu)造方法中昔脯。實(shí)現(xiàn)Callable接口的方法需要?jiǎng)?chuàng)建一個(gè)FutureTask類的對(duì)象包裝Callable接口的實(shí)現(xiàn)類啄糙,然后傳入Thread類的構(gòu)造方法中。
- 由于Java的單繼承機(jī)制云稚,繼承Thread類后就不能再繼承其他類了隧饼,所以繼承Thread類的方式不夠靈活,相反静陈,實(shí)現(xiàn)Runable接口與Callable接口的方式比較靈活燕雁。
- 繼承Thread類多個(gè)線程不能共享資源诞丽,而實(shí)現(xiàn)Runable接口與Callable接口的方式可以在實(shí)現(xiàn)類中定義一個(gè)靜態(tài)變量實(shí)現(xiàn)資源的共享。
- 繼承Thread類與實(shí)現(xiàn)Runable接口的方式?jīng)]有返回值拐格,實(shí)現(xiàn)Callable接口的方式可以獲得方法執(zhí)行的返回值僧免。