生活随笔
收集整理的這篇文章主要介紹了
获取一亿数据获取前100个最大值
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
package?cn.usst.tophundred.quicksort;?? ?? import?java.util.Random;?? ? ? ? ? ? ? ?? ?? public?class?TopHundredQuickSort?{?? ?? ????public?static?void?main(String[]?args)?{?? ?????????? ????????int?number?=?100000000;?? ?????????? ????????int?k?=?100;?? ?????????? ????????int?range?=?1000000001;?? ?????????? ?????????? ????????int[]?array?=?new?int[number];?? ?????????? ????????Random?random?=?new?Random();?? ????????for(int?i=0;?i<number;?i++){?? ????????????array[i]?=?random.nextInt(range);?? ????????}?? ?????????? ????????TopHundredQuickSort?topHundred?=?new?TopHundredQuickSort();?? ?????????? ?????????? ????????long?t1?=?System.currentTimeMillis();?? ????????topHundred.tophundred(array,?0,?array.length-1,?k);?? ?????????? ?????????? ????????long?t2?=?System.currentTimeMillis();?? ?????????? ????????System.out.println("The?total?execution?time?of?quicksort?based?method?is"?+?(t2-t1)?+?"?millisecond");?? ?????????? ?????????? ????????System.out.println("The?top?"?+?k?+?"?largest?values?are:");?? ????????for(int?i=0;?i<k;?i++){?? ????????????System.out.println(array[i]);?? ????????}?? ????}?? ?? ????private?void?tophundred(int[]?array,?int?start,?int?end,?int?k)?{?? ????????int?switchPointer?=?start;?? ?????????? ????????int?pivot?=?array[end];???? ????????for(int?i=start;?i<end;?i++){?? ????????????if(array[i]?>=?pivot){?? ????????????????swap(array,?switchPointer,?i);?? ????????????????switchPointer++;?? ????????????}?? ????????}?? ?????????? ?????????? ????????swap(array,?end,?switchPointer);?? ?????????? ????????if(switchPointer?<?k-1){?? ????????????tophundred(array,?switchPointer+1,?end,?k);?? ????????}else?if(switchPointer?==?k-1){?? ????????????return;?? ????????}else{?? ????????????tophundred(array,?0,?switchPointer-1,?k);?? ????????}?? ?????????? ????}?? ?? ????private?void?swap(int[]?array,?int?i,?int?j)?{?? ????????int?temp?=?array[i];?? ????????array[i]?=?array[j];?? ????????array[j]?=?temp;?? ????}?? ?? }??
?
【來自程序員面試寶典】有1千萬條短信,找出重復出現最多的前10條
題目:有1千萬條短信,有重復,以文本文件的形式保存,一行一條,有重復。請用5分鐘時間,找出重復出現最多的前10條。
解析:對于本題來說,某些面試者想用數據庫的辦法來實現:首先將文本導入數據庫,再利用select語句某些方法得出前10條短信。但實際上用數據庫是滿足不了5分鐘解決這個條件的。這是因為1千萬條短信即使1秒鐘錄入1萬條(這已經算是很快的數據錄入了)5分鐘才300萬條。即使真的能在5分鐘內錄入完1千萬條,也必須先建索引,不然sql語句5分鐘內肯定得不出結果。但對1千萬條記錄建索引即使在5分鐘之內都不可能完成的。所以用數據庫的辦法是不行的。
? ? ? 這種類型的題之所以會出現,這是因為互聯網公司無時無刻都在需要處理由用戶產生的海量數據/日志,所以海量數據的題現在很熱,基本上互聯網公司都會考。重點考察的是你的數據結構設計和算法的基本功。類似題目是如何根據關鍵詞搜索訪問最多的前10個網站。
答案:
方法1:可以用哈希表的方法對1千萬條分成若干組進行邊掃描邊建散列表。第一次掃描,取首字節,尾字節,中間隨便兩字節作為Hash Code,插入到hash table中。并記錄其地址和信息長度和重復次數,1千萬條信息,記錄這幾個信息還放得下。同Hash Code且等長就疑似相同,比較一下。相同記錄只加1次進hash table,但將重復次數加1。一次掃描以后,已經記錄各自的重復次數,進行第二次hash table的處理。用線性時間選擇可在O(n)的級別上完成前10條的尋找。分組后每份中的top10必須保證各不相同,可hash來保證,也可直接按hash值的大小來分類。
方法2:可以采用從小到大排序的方法,根據經驗,除非是群發的過節短信,否則字數越少的短信出現重復的幾率越高。建議從字數少的短信開始找起,比如一開始搜一個字的短信,找出重復出現的top10并分別記錄出現次數,然后搜兩個字的,依次類推。對于對相同字數的比較常的短信的搜索,除了hash之類的算法外,可以選擇只抽取頭、中和尾等幾個位置的字符進行粗判,因為此種判斷方式是為了加快查找速度但未能得到真正期望的top10,因此需要做標記;如此搜索一遍后,可以從各次top10結果中找到備選的top10,如果這top10中有剛才做過標記的,則對其對應字數的所有短信進行精確搜索以找到真正的top10并再次比較。
方法3:可以采用內存映射的辦法,首先1千萬條短信按現在的短信長度將不會超過1G空間,使用內存映射文件比較合適。可以一次映射(當然如果更大的數據量的話,可以采用分段映射),由于不需要頻繁使用文件I/O和頻繁分配小內存,這將大大提高數據的加載速度。其次,對每條短信的第i(i從0到70)個字母按ASCII嘛進行分組,其實也就是創建樹。i是樹的深度,也是短信第i個字母。
? ? 該問題主要是解決兩方面的內容,一是內容加載,二是短信內容比較。采用文件內存映射技術可以解決內容加載的性能問題(不僅僅不需要調用文件I/O函數,而且也不需要每讀出一條短信都分配一小塊內存),而使用樹技術可以有效減少比較的次數。
【來自程序員面試寶典】執行數據庫查詢時,如果要查詢的數據有很多,假設有1000萬條,用什么方法可以提高查詢效率(速度)?在數據庫方面或Java代碼方面有什么優化的辦法?
1.在數據庫設計方面
? (1) 建立索引
? (2) 分區(MySQL,比如按時間分區)
? (3) 限制字段長度
2.在數據庫I/O方面
? (1) 增加緩沖區
? (2) 如果設計標的級聯,不同的表存儲在不同的磁盤上,以增加I/O的讀寫效率
3.在SQL語句方面
? (1) 優化SQL語句,減少比較的次數
? (2) 限制返回的條目數(mysql中使用limit)
4.在Java方面
?如果是反復使用的查詢,使用PreparedStatement減少查詢的次數。
來源:http://blog.csdn.net/ankeyuan/article/details/39555483
總結
以上是生活随笔為你收集整理的获取一亿数据获取前100个最大值的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。