Form一個問題
假設百度搜索引擎一天會搜索M億條URL,如何根據URL被搜索的次數來找出次數最高的N個URL呢?
個人有一個抽象的思路:
- 先對所有的URL日誌文檔進行整合,同一類型的當作一個結點,利用B或者B+樹搜索的優秀性能來處理
- 再使用優先隊列或者是最大值堆來進行一個排序
正確與否先撇開不談,整合同類URL的過程中會給後續排序減少大量的工作量(但究竟對於這種億級的數據量還是隻有一個朦朧的概念)。不管怎麼說,先來研究一下Java中的優先隊列好了
優先隊列和遍歷層次樹
優先隊列(PriorityQueue)是不同於普通隊列的先進先出的隊列,每次從隊列中取出的是具有最高優先權的元素。這是從Java1.5開始引入的數據結構的接口。
// TestPriorityQueue.java
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
class Student{
int id;
String name;
public Student(){
this.id = 0;
this.name = "";
}
public Student(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
public class TestPriorityQueue {
private static Comparator<Student> stCompare = new Comparator<Student>(){
// 重寫了比較器中的compare方法,否則直接把Student類型的元素加入優先隊列會報錯
@Override
public int compare(Student st1,Student st2){
// 針對Student的id屬性進行比較
return (int)(st1.getId()-st2.getId());
}
};
public static void main(String[] args){
Queue<Integer> number = new PriorityQueue<Integer>();// 存放int類型的數據
Random rand = new Random();
for(int i=0;i<5;i++){
//因爲實例化時使用了默認的比較器,所以隊列新增的元素時都會自動排序
number.add(rand.nextInt(100));
}
for(Integer i : number){
System.out.println(i);
}
System.out.println();
// ----- 下面開始排序自定義類
// 把重寫後的比較器作爲參數傳入優先隊列
Queue<Student> students = new PriorityQueue<Student>(5,stCompare);
for(int i=0;i<5;i++){
students.add(new Student(rand.nextInt(10),String.valueOf(i)));
}
// 預計的輸出結果會是:不管st.name是怎樣的順序,但是st.id一定是由小到大
for(Student st : students){
System.out.println(st.id + " " + st.name);
}
}
}
遍歷層次樹
怎麼百度的都是概念層次樹(黑人問號….),相關的知識有如何層次遍歷二叉樹,思路是
- 使其根節點入隊列,然後出隊進行訪問
- 若左子節點不爲空,使左子節點入隊
- 若該節點的右子節點,再使右子節點入隊
- 重複上面三個步驟,直到訪問了所有節點
大概的思路是這樣,開的坑已經夠多了,這個就先放後面好了 /:doge
又回到了HashMap高性能讀寫方法?
其實是自己沒有繞出這個圈,那天和dalao討論的時候,ta認爲沒有什麼優化的方法,畢竟HashMap已經被寫好放在jar中了,若是使用,怎麼會優化呢?
of cause,自己擼一個HashMap實現,這就引出了一個重點,在我們討論這個問題的時候,前提是什麼?,有說可以自己擼嗎?不知道,有說必須要用jdk中的HashMap嗎?不知道。
So,…….
日常總結
今天被教育“凡是遇到問題的時候,第一個想到的就應該是前提條件”,沒有前提條件,問題是不受約束的。看似是一個誰都懂的道理,但真的很多時候,會被自己潛意識認爲的條件侷限了自己的思維。就這樣。