阿里电话面试问题----100万个URL如何找到出现频率最高的前100个?
内推阿里电话面试中面试官给我出的一个题:
我想的头一个解决方案,就是放到stl 的map里面对出现的频率作为pair的第二个字段进行排序,之后按照排序结果返回:
下面口说无凭,show your code,当然在讨论帖子中遭遇了工程界大牛的sql代码在技术上的碾压。什么是做工程的,什么是工程师的思维,不要一味的埋头搞算法。
讨论帖:
http://bbs.csdn.net/topics/391080906
python 抓取百度搜索结果的讨论贴:
http://bbs.csdn.net/topics/391077668
实验数据,python从百度抓得:
# -*- coding: utf-8 -*-
"""
Spyder Editor This is a temporary script file.
""" import urllib2
import re
import os #connect to a URL
#一页的搜索结果中url大概是200个左右
file_url = open('url.txt','ab+')
#搜索框里的东西,这块可以设置成数字好让每次搜索的结果不一样
search = '123'
url = "http://www.baidu.com/s?wd="+search def setUrlToFile():
website = urllib2.urlopen(url)
#read html code html = website.read() #use re.findall to get all the links links = re.findall('"((http|ftp)s?://.*?)"', html) for s in links:
print s[0]
if len(s[0]) < 256:
file_url.write(s[0]+'\r\n') #收集实验数据
for i in range(0,50):
setUrlToFile() file_url.close() ###需要重新打开再读一下
file_url = open('url.txt','r')
file_lines = len(file_url.readlines())
print "there are %d url in %s" %(file_lines,file_url)
file_url.close()
方法1:
c++ 写的读 url.txt放到map里面
对map<string , int>的value进行排序,得到前100个
运行一下也就55s,还是很快的,url长度进行了限制小于256个字符
#pragma once
/*
//计算代码段运行时间的类
//
*/
#include <iostream> #ifndef ComputeTime_h
#define ComputeTime_h //单位毫秒 class ComputeTime
{
private:
int Initialized;
__int64 Frequency;
__int64 BeginTime; public: bool Avaliable();
double End();
bool Begin();
ComputeTime();
virtual ~ComputeTime(); }; #endif
#include "stdafx.h"
#include "ComputeTime.h"
#include <iostream>
#include <Windows.h> ComputeTime::ComputeTime()
{
Initialized=QueryPerformanceFrequency((LARGE_INTEGER *)&Frequency);
} ComputeTime::~ComputeTime()
{ } bool ComputeTime::Begin()
{
if(!Initialized)
return 0; return QueryPerformanceCounter((LARGE_INTEGER *)&BeginTime);
} double ComputeTime::End()
{
if(!Initialized)
return 0; __int64 endtime; QueryPerformanceCounter((LARGE_INTEGER *)&endtime); __int64 elapsed = endtime-BeginTime; return ((double)elapsed/(double)Frequency)*1000.0; //单位毫秒
} bool ComputeTime::Avaliable()
{
return Initialized;
} // sortUrl.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
//#include <utility>
#include <vector>
#include <map>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include "ComputeTime.h" using namespace std; map<string,int> urlfrequency; typedef pair<string, int> PAIR; struct CmpByValue
{
bool operator()(const PAIR& lhs, const PAIR& rhs)
{
return lhs.second > rhs.second;
}
}; void find_largeTH(map<string,int> urlfrequency)
{
//把map中元素转存到vector中 ,按照value排序
vector<PAIR> url_quency_vec(urlfrequency.begin(), urlfrequency.end());
sort(url_quency_vec.begin(), url_quency_vec.end(), CmpByValue());
//url_quency_vec.size()
for (int i = 0; i != 100; ++i)
{
cout<<url_quency_vec[i].first<<endl;
cout<<url_quency_vec[i].second<<endl;
}
} //urlheap的建立过程,URL插入时候存在的
void insertUrl(string url)
{
pair<map<string ,int>::iterator, bool> Insert_Pair;
Insert_Pair = urlfrequency.insert(map<string, int>::value_type(url,1)); if (Insert_Pair.second == false)
{
(Insert_Pair.first->second++);
} } int _tmain(int argc, _TCHAR* argv[])
{
fstream URLfile;
char buffer[1024];
URLfile.open("url.txt",ios::in|ios::out|ios::binary); if (! URLfile.is_open())
{ cout << "Error opening file"; exit (1); }
else
{
cout<<"open file success!"<<endl;
} ComputeTime cp;
cp.Begin();
int i = 0;
while (!URLfile.eof())
{
URLfile.getline (buffer,1024);
//cout << buffer << endl;
string temp(buffer);
//cout<<i++<<endl;
insertUrl(temp);
} find_largeTH(urlfrequency); cout<<"running time: "<<cp.End()<<"ms"<<endl; getchar();
//system("pause");
return 0;
}
实验结果:55s还不算太差,可以接受,毕竟是头脑中的第一个解决方案。
方法2:
hash code 版本,只是不知道怎么 hash和url关联起来:
// urlFind.cpp : 定义控制台应用程序的入口点。
// // sortUrl.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h" #include <vector>
#include <map>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_map>
#include "ComputeTime.h" using namespace std; map<unsigned int,int> urlhash; typedef pair<unsigned int, int> PAIR; struct info{
string url;
int cnt;
bool operator<(const info &r) const {
return cnt>r.cnt;
}
}; unordered_map<string,int> count; //priority_queue<info> pq; struct CmpByValue
{
bool operator()(const PAIR& lhs, const PAIR& rhs)
{
return lhs.second > rhs.second;
}
}; void find_largeTH(map<unsigned int,int> urlhash)
{
//把map中元素转存到vector中 ,按照value排序
vector<PAIR> url_quency_vec(urlhash.begin(), urlhash.end());
sort(url_quency_vec.begin(), url_quency_vec.end(), CmpByValue());
//url_quency_vec.size()
for (int i = 0; i != 100; ++i)
{
cout<<url_quency_vec[i].first<<endl;
cout<<url_quency_vec[i].second<<endl;
}
} // BKDR Hash Function
unsigned int BKDRHash(char *str)
{
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0; while (*str)
{
hash = hash * seed + (*str++);
} return (hash & 0x7FFFFFFF);
} //
void insertUrl(string url)
{ unsigned int hashvalue = BKDRHash((char *)url.c_str());
pair<map<unsigned int ,int>::iterator, bool> Insert_Pair;
Insert_Pair = urlhash.insert(map<unsigned int, int>::value_type(hashvalue,1)); if (Insert_Pair.second == false)
{
(Insert_Pair.first->second++);
} } int _tmain(int argc, _TCHAR* argv[])
{
fstream URLfile;
char buffer[1024];
URLfile.open("url.txt",ios::in|ios::out|ios::binary); if (! URLfile.is_open())
{ cout << "Error opening file"; exit (1); }
else
{
cout<<"open file success!"<<endl;
} ComputeTime cp;
cp.Begin();
int i = 0;
while (!URLfile.eof())
{
URLfile.getline (buffer,1024);
//cout << buffer << endl;
string temp(buffer);
//cout<<i++<<endl;
insertUrl(temp);
} find_largeTH(urlhash); cout<<"running time: "<<cp.End()<<"ms"<<endl; getchar();
//system("pause");
return 0;
}
性能15秒左右:缺点在于没有把hashcode和url进行关联,技术的处理速度已经非常可观了
方法3:
下面用STL的hash容器unordered_map,和优先队列(就是堆)来实现这个问题。
// urlFind.cpp : 定义控制台应用程序的入口点。
// // sortUrl.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h" #include <vector>
#include <map>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_map>
#include <queue>
#include "ComputeTime.h" using namespace std; typedef pair<string, int> PAIR; struct info
{
string url;
int cnt;
bool operator<(const info &r) const
{
return cnt<r.cnt;
}
}; unordered_map<string,int> hash_url; priority_queue<info> pq; void find_largeTH(unordered_map<string,int> urlhash)
{ unordered_map<string,int>::iterator iter = urlhash.begin();
info temp;
for (; iter!= urlhash.end();++iter)
{
temp.url = iter->first;
temp.cnt = iter->second;
pq.push(temp);
} for (int i = 0; i != 100; ++i)
{ cout<<pq.top().url<<endl;
cout<<pq.top().cnt<<endl;
pq.pop();
}
} void insertUrl(string url)
{ pair<unordered_map<string ,int>::iterator, bool> Insert_Pair;
Insert_Pair = hash_url.insert(unordered_map<string, int>::value_type(url,1)); if (Insert_Pair.second == false)
{
(Insert_Pair.first->second++);
} } int _tmain(int argc, _TCHAR* argv[])
{
fstream URLfile;
char buffer[1024];
URLfile.open("url.txt",ios::in|ios::out|ios::binary); if (! URLfile.is_open())
{ cout << "Error opening file"; exit (1); }
else
{
cout<<"open file success!"<<endl;
} ComputeTime cp;
cp.Begin();
int i = 0;
while (!URLfile.eof())
{
URLfile.getline (buffer,1024);
//cout << buffer << endl;
string temp(buffer);
//cout<<i++<<endl;
insertUrl(temp);
} find_largeTH(hash_url); cout<<"running time: "<<cp.End()<<"ms"<<endl; getchar();
//system("pause");
return 0;
}
基本上算是算法里面比较优秀的解决方案了,面试官如果能听到这个方案应该会比较欣喜。
方法4:实验耗时未知,技术上碾压了上述解决方案,中高年轻人,不要重复造轮子!哈哈
数据库,SQL语句:
load data infile "d:/bigdata.txt" into table tb_url(url); SELECT
url,
count(url) as show_count
FROM
tb_url
GROUP BY url
ORDER BY show_count desc
LIMIT 100
阿里电话面试问题----100万个URL如何找到出现频率最高的前100个?的更多相关文章
- 阿里电话面试问题----100万个URL怎样找到出现频率最高的前100个?
内推阿里电话面试中面试官给我出的一个题: 我想的头一个解决方式.就是放到stl 的map里面对出现的频率作为pair的第二个字段进行排序.之后依照排序结果返回: 以下口说无凭,show your co ...
- SQL 从100万条记录中的到 成绩最高的记录
从100万条记录中的到 成绩最高的记录 问题分析:要从一张表中找到成绩最高的记录并不难,有很多种办法,最简单的就是利用TOP 1 select top 1 * from student order b ...
- 阿里Java开发电话面试经历--惨败
近期准备跳槽,想试试知名大企业--阿里.经过boss直聘上一些内部人员的内推,有幸获得了一次电话面试的机会.(虽然在面试开始之前就大概知道结果是如何,但是也总得试试自己个有多水,哈哈哈...) 跟大家 ...
- 阿里P8面试官:如何设计一个扛住千万级并发的架构?
大家先思考一个问题,这也是在面试过程中经常遇到的问题. 如果你们公司现在的产品能够支持10W用户访问,你们老板突然和你说,融到钱了,会大量投放广告,预计在1个月后用户量会达到1000W,如果这个任务交 ...
- Java 最常用类(前100名)来自一万个开源项目
大部分的 Java 软件开发都会使用到各种不同的库.近日我们从一万个开源的 Java 项目中进行分析,从中提取出最常用的 Java 类,这些类有来自于 Java 的标准库,也有第三方库.每个类在同一个 ...
- 上海支付宝终面后等了两周,没能收到offer却来了杭州淘宝的电话面试
上上周一(14/12/22)上海支付宝hr终面 http://www.cnblogs.com/zhanghaoh/p/4178386.html 苦苦等了两周,没能如愿收到offer,却在今天等来了 杭 ...
- 电话面试问答Top 50 --[伯乐在线]
今年是2015年,在过去几年中,电面(电话面试)是筛选程序员职位候选人的最流行的方式.它让雇佣双方很容易互相了解对方,候选人不需要去未来雇主的所在地,面试官也不用做额外的安排.这是我介绍程序员面试问题 ...
- 100万套PPT模板,包含全宇宙所有主题类型PPT,绕宇宙100圈,持续更新
100万套PPT模板,包含全宇宙所有主题类型PPT(全部免费,都是精品,没有一张垃圾不好看的PPT,任何一张PPT拿来套入自己的信息就可以立马使用),绕宇宙100圈,任意一个模板在某文库上都价不菲.强 ...
- 如何通过Dataphin构建数据中台新增100万用户?
欢迎来到数据中台小讲堂!这一期我们来看看,作为阿里巴巴数据中台(OneData - OneModel.OneID.OneService)方法论的产品载体,Dataphin如何帮助传统零售企业实现数字化 ...
随机推荐
- d4d#9 玩Docker只要浏览器就够了,PWD是个神奇的网站
本文是d4d系列的第9篇,在这一篇中给大家介绍一个学习Docker最为快捷高效的方式,你不需要自己搭建环境,也不用担心把自己的开发环境搞乱,你需要的只是一个浏览器,就可以立即开始学习Docker的常用 ...
- Node.js HTTP
稳定性: 3 - 稳定 使用 HTTP 服务器或客户端功能必须调用 require('http'). Node 里的 HTTP 接口支持协议里原本比较难用的特性.特别是很大的或块编码的消息.这些接口不 ...
- springMVC源码分析--ViewNameMethodReturnValueHandler返回值处理器(三)
之前两篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)和springMVC源码分析--HandlerMethodReturnValu ...
- Java经典设计模式之七大结构型模式(附实例和详解)
博主在大三的时候有上过设计模式这一门课,但是当时很多都基本没有听懂,重点是也没有细听,因为觉得没什么卵用,硬是要搞那么复杂干嘛.因此设计模式建议工作半年以上的猿友阅读起来才会理解的比较深刻.当然,你没 ...
- Dynamics CRM build numbers
Dynamics CRM build numbers CRM各大版本及补丁列表,整理的很全
- Linux动态频率调节系统CPUFreq之三:governor
在上一篇文章中,介绍了cpufreq的core层,core提供了cpufreq系统的初始化,公共数据结构的建立以及对cpufreq中其它子部件提供注册功能.core的最核心功能是对policy的管理, ...
- 全文检索 Lucene(4)
经过了前面几篇文章的学习,我们基本上可以适用Lucene来开发我们的站内搜索应用了.但是观察一下目前的主流的搜索引擎,我们会发现查询结果会有高亮的显示效果.所以,今天我们就来学习一下,给Lucene添 ...
- 保存图片到SD卡
添加SD卡写权限 方法 public void saveMyBitmap(String bitName, Bitmap mBitmap) { File f = new File("/sdca ...
- Android简易实战教程--第二十话《通过广播接收者,对拨打电话外加ip号》
没睡着觉,起来更篇文章吧哈哈!首先祝贺李宗伟击败我丹,虽然我是支持我丹的,但是他也不容易哈哈,值得尊敬的人!切入正题:这一篇来介绍个自定义广播接收者. 通常我们在外拨电话的时候,一般为使用网络电话.如 ...
- 关于activitygroup过时,用frament替换操作
现在Fragment的应用真的是越来越广泛了,之前Android在3.0版本加入Fragment的时候,主要是为了解决Android Pad屏幕比较大,空间不能充分利用的问题,但现在即使只是在手机上, ...