教你怎么高效秒杀掉:99%的雅量数据处理面试题

话说有了WebBrowser类,终于不用自个儿手动封装SHDocVw的AxWebBrowser那个ActiveX控件了。这几个类若是单单作为一个和IE一模一样浏览器,那就太

作者:July
出处:结构之法算法之道blog

干燥了(还不如直接用IE呢)。那么,无论我们是想做一个“定制版IE”,依然愿意接纳HTML来做用户界面(指WinApp而非WebApp。许多单机软件

 

,包罗Windows的协理扶助中央,都以HTML做的),都必不可少Windows
Form和含有在WebBrowser中的Web页面的交互。本文将因而多少个实际的例子,初

前言

  
一般而言,标题含有“秒杀”,“99%”,“史上最全/最强”等词汇的高频都脱不了哗众取宠之嫌,但更是来讲,如若读者读罢此文,却无其余收获,那么,作者也乐意承受那样的罪名,:-),同时,此文可以作为是对这篇小说:十道海量数据处理面试题与十个艺术大计算的相似抽象性总计。

   
毕竟受作品和理论之限,本文将舍弃绝半数以上的细节,只谈艺术/方式论,且尊敬用最开端最直白的语言演讲相关题材。最终,有好几无法不强调的是,全文行文是依据面试题的剖析基础之上的,具体实施进程中,仍然得具体处境具体分析,且场景也远比本文所述的其余一种意况复杂得多。

    OK,若有其余难题,欢迎随时不吝赐教。感激。

步介绍一下WinForm和WebBrowser所包罗的Web页面之间的竞相。

号称海量数据处理?

  
所谓海量数据处理,无非就是依照海量数据上的存储、处理、操作。何谓海量,就是数据量太大,所以造成要么是心有余而力不足在较短期内快捷解决,要么是数据太大,导致力不从心一遍性装入内存。

   
那化解办法呢?针对时间,大家得以行使巧妙的算法搭同盟适的数据结构,如Bloom
filter/Hash/bit-map/堆/数据库或倒排索引/trie树,针对空中,无非就一个措施:大而化小:分而治之/hash映射,你不是说规模太大嘛,那简单啊,就把规模大化为规模小的,各种击破不就完了呗。

   
至于所谓的单机及集群难题,通俗点来讲,单机就是拍卖装载数据的机械有限(只要考虑cpu,内存,硬盘的数量交互),而集群,机器有多辆,适合分布式处理,并行总结(越来越多着想节点和节点间的数码交互)。

    再者,通过本blog内的关韦世豪量数据处理的稿子:Big Data
Processing
,大家早已大概知道,处理海量数据难题,无非就是:

 

  1. 分而治之/hash映射 + hash总计 + 堆/急速/归并排序;
  2. 双层桶划分
  3. Bloom filter/Bitmap;
  4. Trie树/数据库/倒排索引;
  5. 外排序;
  6. 分布式处理之Hadoop/Mapreduce。

   
上面,本文第一局地、从set/map谈到hashtable/hash_map/hash_set,简要介绍下set/map/multiset/multimap,及hash_set/hash_map/hash_multiset/hash_multimap之差别(万丈高楼平地起,基础最重点),而本文第二部分,则指向上述那6种办法方式结合对应的海量数据处理面试题分别实际阐释。

 

上面的代码假如你早已创立了一个Windows
Form,上边有一个WebBrowser名为“webBrowser”。

率先片段、从set/map谈到hashtable/hash_map/hash_set

   
稍后本文第二有的团长多次关乎hash_map/hash_set,上面稍稍介绍下这个器皿,以作为基础准备。一般的话,STL容器分二种,

  • 连串式容器(vector/list/deque/stack/queue/heap),
  • 关联式容器。关联式容器又分为set(集合)和map(映射表)两大类,以及那两大类的衍生体multiset(多键集合)和multimap(多键映射表),那几个器皿均以RB-tree完毕。别的,还有第3类关联式容器,如hashtable(散列表),以及以hashtable为底层机制形成的hash_set(散列集合)/hash_map(散列映射表)/hash_multiset(散列多键集合)/hash_multimap(散列多键映射表)。相当于说,set/map/multiset/multimap都内含一个RB-tree,而hash_set/hash_map/hash_multiset/hash_multimap都内含一个hashtable。

   
所谓关联式容器,类似关联式数据库,每笔数据或每种元素都有一个键值(key)和一个实值(value),即所谓的Key-Value(键-值对)。当成分被插入到关联式容器中时,容器内部结构(RB-tree/hashtable)便根据其键值大小,以某种特定规则将以此因素放置于适当地点。

   
 比如,在MongoDB中,文档(document)是最宗旨的数据社团方式,各种文档以Key-Value(键-值对)的点子社团起来。一个文档可以有八个Key-Value组合,每一种Value可以是区其他连串,比如String、Integer、List等等。 
{ “name” : “July”,  
   “sex” : “male”,  
   “age” : 23 }  

 

set/map/multiset/multimap

   
set,同map一样,所有因素都会按照元素的键值自动被排序,因为set/map两者的兼具各样操作,都只是转而调用RB-tree的操作行为,但是,值得注意的是,两者都不容许多个要素有雷同的键值。
   
差其余是:set的要素不像map那样可以而且具备实值(value)和键值(key),set成分的键值就是实值,实值就是键值,而map的装有因素都是pair,同时拥有实值(value)和键值(key),pair的首先个因素被视为键值,第三个要素被视为实值。
   
至于multiset/multimap,他们的性状及用法和set/map完全相同,唯一的差距就在于它们允许键值重复,即怀有的插入操作基于RB-tree的insert_equal()而非insert_unique()。

hash_set/hash_map/hash_multiset/hash_multimap

   
hash_set/hash_map,两者的总体操作都是依照hashtable之上。不一致的是,hash_set同set一样,同时具有实值和键值,且实质就是键值,键值就是实值,而hash_map同map一样,每一种要素同时拥有一个实值(value)和一个键值(key),所以其选择方法,和上面的map基本相同。但鉴于hash_set/hash_map都以依照hashtable之上,所以不有所自动排序功效。为啥?因为hashtable没有机关排序功用。
   
至于hash_multiset/hash_multimap的特色与地点的multiset/multimap完全相同,唯一的距离就是它们的平底已毕机制是hashtable,所以它们的成分都不会被电动排序,然则也都同意键值重复。

   
所以,综上,说白了,什么样的协会决定其何等的质量,因为set/map/multiset/multimap都以依据RB-tree之上,所以有自动排序作用,而hash_set/hash_map/hash_multiset/hash_multimap都以基于hashtable之上,所以不包蕴自动排序功用,至于加个前缀multi_独自就是同意键值重复而已。

   
其余,关于怎样hash,请看此篇小说:http://blog.csdn.net/v\_JULY\_v/article/details/6256463;关于红黑树,请参看blog内密密麻麻小说:http://blog.csdn.net/v\_july\_v/article/category/774945,关于hash_map的具体使用,可看看此篇小说:http://blog.csdn.net/sdhongjun/article/details/4517325

    OK,接下去,请看本文第二局地、处理海量数据难题之六把密匙。

 

Study
Case 1:用WinForm的伊芙nt Handler响应Web页面的风云

其次局地、处理海量数据难题之六把密匙

现行有如此一个Windows
Application,它的界面上唯有一个WebBrowser,显示一个地点的HTML文件作为界面。未来的题材是,所有逻辑都得以置身

密匙一、分而治之/Hash映射 + Hash计算 + 堆/飞快/归并排序

1、海量日志数据,提取出某日访问百度次数最多的非常IP。

   
既然是海量数据处理,那么同理可得,给我们的多寡那就必定是海量的。针对那么些数额的海量,大家怎样出手呢?对的,无非就是分而治之/hash映射

  • hash总结 + 堆/快捷/归并排序,说白了,就是先映射,而后总括,最终排序:
  1. 分而治之/hash映射:针对数据太大,内存受限,只可以是:把大文件化成(取模映射)小文件,即16字方针:大而化小,各种击破,减少规模,各种消除
  2. hash统计:当大文件转载了小文件,那么大家便得以行使常规的hash_map(ip,value)来进行频率总计。
  3. 堆/疾速排序:总括完明白后,便举办排序(可拔取堆排序),获得次数最多的IP。

   具体而论,则是:
“首先是这一天,并且是造访百度的日记中的IP取出来,每个写入到一个大文件中。注意到IP是32位的,最多有个2^32个IP。同样可以动用映射的措施,比如模1000,把全体大文件映射为1000个小文件,再找出各样小文中出现频率最大的IP(能够使用hash_map举办频率总计,然后再找出作用最大的多少个)及相应的作用。然后再在那1000个最大的IP中,找出卓殊频率最大的IP,即为所求。”–十道海量数据处理面试题与十个章程大总括

   
注:Hash取模是一种等价映射,不会存在同一个要素分散到差异小文件中去的情况,即那里运用的是mod1000算法,那么相同的IP在hash后,只恐怕落在同一个文书中,不容许被分流的。

   
那终究怎么是hash映射呢?小编换个角度举个浅显直白的事例,如本文的URL是:http://blog.csdn.net/v\_july\_v/article/details/7382693,当本身把这些URL发布在新浪上,便被映射成了:http://t.cn/zOixljh,于此,大家发现URL本人的长短被减少了,但那七个URL对应的小说的是平等篇即本文。OK,有趣味的,还足以再领悟下一致性hash算法,见此文第五有的:http://blog.csdn.net/v\_july\_v/article/details/6879101

2、搜索引擎会通过日记文件把用户每趟搜寻使用的保有检索串都记录下来,每种查询串的长短为1-255字节。

   
即使如今有一千万个记录(那么些查询串的重复度比较高,即便总数是1千万,但只要除去重复后,不超过3百万个。一个查询串的重复度越高,表达查询它的用户越来越多,相当于越吃香),请您计算最热点的10个查询串,须求拔取的内存不可以超越1G。

   
由地点第1题,我们精晓,数据大则划为小的,但假如数额规模比较小,能两回性装入内存呢?比如这第2题,即便有一千万个Query,但是由于重复度相比高,由此实际只有300万的Query,逐个Query255Byte,由此大家得以设想把他们都放进内存中去,而后天只是亟需一个恰当的数据结构,在此地,Hash
Table相对是我们先行的选择。所以大家抛开分而治之/hash映射的法门,直接上hash计算,然后排序。So,

  1. hash总计:先对那批海量数据预处理(维护一个Key为Query字串,Value为该Query出现次数的HashTable,即hash_map(Query,Value),每一趟读取一个Query,假若该字串不在Table中,那么投入该字串,并且将Value值设为1;要是该字串在Table中,那么将该字串的计数加一即可。最终我们在O(N)的小时复杂度内用Hash表完结了计算;
  2. 堆排序:第二步、借助堆那个数据结构,找出Top
    K,时间复杂度为N‘logK。即借助堆结构,大家能够在log量级的时辰内寻找和调动/移动。由此,维护一个K(该难题中是10)大小的小根堆,然后遍历300万的Query,分别和根成分举办相比所以,我们最终的日子复杂度是:O(N) +
    N’*O(logK),(N为1000万,N’为300万)。

   
别忘了那篇小说中所述的堆排序思路:“维护k个成分的很小堆,即用容量为k的微小堆存储起始遍历到的k个数,并借使它们即是最大的k个数,建堆费时O(k),并调动堆(费时O(logk))后,有k1>k2>…kmin(kmin设为小顶堆中细小成分)。继续遍历数列,每趟遍历一个成分x,与堆顶成分比较,若x>kmin,则更新堆(用时logk),否则不创新堆。那样下来,总费时O(k*logk+(n-k)*logk)=O(n*logk)。此措施得益于在堆中,查找等各项操作时间复杂度均为logk。”–其三章续、Top
K算法难点的贯彻

   
当然,你也得以动用trie树,关键字域存该查询串出现的次数,没有出现为0。最终用10个因素的细微推来对出现频率举行排序。

3、有一个1G分寸的一个文件,里面每一行是一个词,词的大大小小不超越16字节,内存限制大小是1M。再次回到频数最高的100个词。
       由地点那八个例题,分而治之 + hash总结 +
堆/连忙排序这一个套路,我们已经起始有了屡试不爽的感觉到。下面,再拿几道再多多验证下。请看此第3题:又是文件很大,又是内存受限,咋做?还是可以如何是好呢?无非照旧:

  1. 分而治之/hash映射:顺序读文件中,对于每种词x,取hash(x)%5000,然后依据该值存到5000个小文件(记为x0,x1,…x4999)中。那样种种文件大约是200k左右。若是中间的一对文件超过了1M大小,还足以听从类似的法子继续往下分,直到分解得到的小文件的尺寸都不当先1M。
  2. hash总结:对每种小文件,接纳trie树/hash_map等计算每一种文件中冒出的词以及对应的效能。
  3. 堆/归并排序:取出出现频率最大的100个词(可以用含100个结点的最小堆),并把100个词及相应的频率存入文件,那样又拿到了5000个文本。最终就是把那5000个公文举行合并(类似于归并排序)的历程了。

4、海量数据分布在100台电脑中,想个办法高效总结出那批数量的TOP10。

    此题与地点第3题类似,

  1. 堆排序:在每台微机上求出TOP10,可以利用包蕴10个因素的堆完结(TOP10小,用最大堆,TOP10大,用最小堆)。比如求TOP10大,大家率先取前10个因素调整成最小堆,尽管发现,然后扫描前面的数目,并与堆顶元素比较,假设比堆顶成分大,那么用该因素交替堆顶,然后再调动为最小堆。最后堆中的元素就是TOP10大。
  2. 求出每台电脑上的TOP10后,然后把那100台微机上的TOP10结缘起来,共1000个数据,再使用方面类似的措施求出TOP10就可以了。

   
上述第4题的此解法,经读者反馈有难点,如举个例子如比如求2个公文中的top2,照你那种算法,倘若第四个文件里有

a 49次

b 50次

c 2次

d 1次

    首个文件里有

a 9次

b 1次

c 11次

d 10次

     尽管第三个文本里出来top2是b(50次),a(49次),第三个公文里出来top2是c(11次),d(10次),然后2个top2:b(50次)a(49次)与c(11次)d(10次)归并,则算出具有的文书的top2是b(50
次),a(49 次),但实在是a(58 次),b(51
次)。是还是不是真是那样吗?若真那样,那作何化解呢?

    正如老梦所述:

   
首先,先把持有的多寡遍历五遍做一遍hash(保险平等的数据条目划分到平等台电脑上举行演算),然后依照hash结果再行分布到100台总结机中,接下去的算法依照从前的即可。

   
最终由于a恐怕出以往不一致的计算机,各有必然的次数,再对各类相同条目举行求和(由于上一步骤中hash之后,也有益每台电脑只要求对自个儿分到的条文内展开求和,不涉及到其他电脑,规模压缩)。

5、有10个公文,逐个文件1G,每一个文件的每一行存放的都以用户的query,每一种文件的query都或者再一次。须求你依据query的频度排序。

   直接上:

  1. hash映射:顺序读取10个文本,依据hash(query)%10的结果将query写入到此外10个文件(记为)中。那样新变化的文件每一个的高低几乎也1G(即使hash函数是随机的)。
  2. hash统计:找一台内设有2G左右的机器,依次对用hash_map(query,
    query_count)来总计每一种query出现的次数。注:hash_map(query,query_count)是用来统计每种query的产出次数,不是储存他们的值,现身四次,则count+1。
  3. 堆/神速/归并排序:利用高效/堆/归并排序依照现身次数举办排序。将排序好的query和对应的query_cout输出到文件中。那样得到了10个排好序的文件(记为)。对那10个公文举办归并排序(内排序与外排序相结合)。

     除此之外,此题还有以下三个方法:
   
方案2:一般query的总量是不难的,只是再也的次数比较多而已,恐怕对此持有的query,一遍性就可以参加到内存了。那样,咱们就足以应用trie树/hash_map等一一贯计算每种query出现的次数,然后按出现次数做火速/堆/归并排序就可以了。

   
方案3:与方案1近似,但在做完hash,分成三个文本后,能够提交三个公文来处理,选拔分布式的架构来拍卖(比如MapReduce),最终再展开统一。

6、
给定a、b多个公文,各存放50亿个url,各个url各占64字节,内存限制是4G,让您找出a、b文件共同的url?

   
可以揣测每一个文件安的深浅为5G×64=320G,远远出乎内存限制的4G。所以不容许将其完全加载到内存中处理。考虑选拔分而治之的章程。

  1. 分而治之/hash映射:遍历文件a,对各类url求取图片 1,然后依据所拿到的值将url分别存储到1000个小文件(记为图片 2)中。那样各种小文件的大概为300M。遍历文件b,采用和a相同的措施将url分别存储到1000小文件中(记为图片 3)。这样处理后,所有或者同样的url都在相应的小文件(图片 4)中,不对应的小文件不容许有同一的url。然后我们只须要出1000对小文件中千篇一律的url即可。
  2. hash总结:求每对小文件中一律的url时,可以把里面一个小文件的url存储到hash_set中。然后遍历另一个小文件的各种url,看其是还是不是在刚刚打造的hash_set中,要是是,那么就是手拉手的url,存到文件之中就能够了。

    OK,此第一种艺术:分而治之/hash映射 + hash总结 +
堆/迅速/归并排序,再看最终三道题,如下:

7、怎么在海量数据中找出双重次数最多的一个?

   
方案1:先做hash,然后求模映射为小文件,求出各个小文件中重复次数最多的一个,并记录重复次数。然后找出上一步求出的数额中再一次次数最多的一个就是所求(具体参考前面的题)。

8、上千万或上亿数据(有再度),总计其中出现次数最多的钱N个数据。

   
方案1:上千万或上亿的数据,未来的机械的内存应该能存下。所以考虑使用hash_map/搜索二叉树/红黑树等来进展统计次数。然后就是取出前N个冒出次数最多的数据了,可以用第2题提到的堆机制已毕。

9、一个文本文件,大概有一万行,每行一个词,需要统计出里面最频仍出现的前10个词,请给出思想,给出时间复杂度分析。

   
 方案1:那题是考虑时间作用。用trie树计算每一种词出现的次数,时间复杂度是O(n*le)(le表示单词的平准长度)。然后是找出出现最频仍的前10个词,能够用堆来兑现,后面的题中早已讲到了,时间复杂度是O(n*lg10)。所以总的时间复杂度,是O(n*le)与O(n*lg10)中较大的哪一个。

 

    接下去,大家来看第三种艺术,双层捅划分。

 

HTML文件里,唯独“关闭”按钮遭遇了不方便——经常,Web页面是一贯不艺术直接控制浏览器的,更不要说得了那一个WinForm程序了。

密匙二、双层桶划分

 

双层桶划分—-其实本质上大概分而治之的思维,重在“分”的技艺上!
  适用范围:第k大,中位数,不重复或重复的数字
  基本原理及中央:因为成分范围很大,不可以使用直接寻址表,所以通过反复分开,逐步确定限制,然后最后在一个足以接受的限制内展开。可以因此反复缩短,双层只是一个例子。
  扩展:
  难题实例:

     
  10、2.5亿个整数中找出不重复的整数的个数,内存空间不足以容纳那2.5亿个整数。
  有点像鸽巢原理,整数个数为2^32,也等于,大家得以将这2^32个数,划分为2^8个区域(比如用单个文件表示一个区域),然后将数据分离到差其余区域,然后区其他区域在行使bitmap就足以向来化解了。也等于说只要有充足的磁盘空间,就足以很有益于的缓解。

       11、5亿个int找它们的中位数。
  那些事例比地点至极更明确。首先我们将int划分为2^16个区域,然后读取数据总结落到各样区域里的数的个数,之后大家依据总计结果就可以判断中位数落到万分区域,同时了解那一个区域中的第几大数刚好是中位数。然后第二次扫描大家只计算落在这一个区域中的那多少个数就能够了。
  实际上,假若不是int是int64,我们可以通过3次那样的划分即可下跌到可以承受的档次。即可以先将int64分成2^24个区域,然后确定区域的第几大数,在将该区域分为2^20个子区域,然后确定是子区域的第几大数,然后子区域里的数的个数唯有2^20,就可以直接使用direct
addr table举行总括了。

 

可是,在.Net
2.0当中,“由Windows Form响应Web页面的事件”已经成为了切实可行。

密匙三:Bloom filter/Bitmap

在.Net
2.0中,整个HTML文档以及其涵盖的次第HTML成分,都和一个个HtmlDocument、HtmlElement之类的.Net对象对应。因而一旦找到那几个“关闭”

Bloom filter

关于什么是Bloom filter,请参考此文:海量数据处理之Bloom
Filter详解

  适用范围:可以用来促成数据字典,举办数据的判重,恐怕集合求交集
  基本原理及大旨:
  对于原理来说很简短,位数组+k个独立hash函数。将hash函数对应的值的位数组置1,查找时只要发现所有hash函数对应位都是1证实存在,很强烈这些历程并不保证查找的结果是100%正确的。同时也不支持删除一个曾经插入的主要字,因为该关键字对应的位会拉动到其它的要紧字。所以一个简约的考订就是
counting Bloom filter,用一个counter数组代替位数组,就足以支撑删除了。
  还有一个相比根本的标题,如何依照输入成分个数n,确定位数组m的大小及hash函数个数。当hash函数个数k=(ln2)*(m/n)时错误率最小。在错误率不大于E的情况下,m至少要等于n*lg(1/E)才能表示任意n个成分的成团。但m还应该更大些,因为还要保障bit数组里最少一半为0,则m应该>=nlg(1/E)*lge
大约就是nlg(1/E)1.44倍(lg代表以2为底的对数)。
  举个例子大家假使错误率为0.01,则此时m应大致是n的13倍。那样k差不离是8个。
  注意那里m与n的单位分歧,m是bit为单位,而n则是以成分个数为单位(准确的就是不一样因素的个数)。平常单个成分的尺寸都以有很多bit的。所以选取bloom
filter内存上经常都以节省的。

  扩展:
  Bloom
filter将聚合中的成分映射到位数组中,用k(k为哈希函数个数)个映射位是不是全1表示成分在不在那个集合中。Counting
bloom
filter(CBF)将位数组中的每一位伸张为一个counter,从而扶助了成分的删除操作。Spectral
Bloom
Filter(SBF)将其与集合成分的产出次数关联。SBF拔取counter中的最小值来就像是表示成分的出现频率。

     
  12、给你A,B八个公文,各存放50亿条URL,每条URL占用64字节,内存限制是4G,让您找出A,B文件共同的URL。假若是两个甚至n个文件呢?

  依照这一个题材大家来计算下内存的占据,4G=2^32大致是40亿*8大约是340亿,n=50亿,如若按出错率0.01算需求的大致是650亿个bit。以后可用的是340亿,相差并不多,那样或然会使出错率上升些。其余假使这个urlip是逐一对应的,就可以转换成ip,则大大简单了。

   
同时,上文的第5题:给定a、b多少个公文,各存放50亿个url,每一个url各占64字节,内存限制是4G,让您找出a、b文件共同的url?假诺允许有肯定的错误率,可以选择Bloom
filter,4G内存大约可以表示340亿bit。将其中一个文件中的url使用Bloom
filter映射为那340亿bit,然后逐一读取其它一个文本的url,检查是还是不是与Bloom
filter,即使是,那么该url应该是一起的url(注意会有肯定的错误率)。

按钮对应的HtmlElement对象,为其click事件添加伊夫nt
Handler即可。

Bitmap

   
至于什么是Bitmap,请看此文:http://blog.csdn.net/v\_july\_v/article/details/6685962。上面关于Bitmap的应用,直接上题,如下第9、10道:

     
13、在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数。

   
方案1:接纳2-Bitmap(逐个数分配2bit,00象征不存在,01象征出现三回,10代表多次,11无意义)举办,共需内存2^32
* 2 bit=1
GB内存,还足以承受。然后扫描那2.5亿个整数,查看Bitmap中相对应位,如果是00变01,01变10,10保持不变。所描完事后,查看bitmap,把对应位是01的整数输出即可。
   
方案2:也可利用与第1题类似的艺术,举办划分小文件的不二法门。然后在小文件中找出不另行的整数,并排序。然后再展开合并,注意去除重复的要素。

      14、腾讯面试题:给40亿个不重复的unsigned
int的平头,没排过序的,然后再给一个数,怎么样高效判断那些数是不是在那40亿个数当中?

    方案1:frome
oo,用位图/Bitmap的点子,申请512M的内存,一个bit位代表一个unsigned
int值。读入40亿个数,设置相应的bit位,读入要询问的数,查占星应bit位是不是为1,为1代表存在,为0表示不设有。

若果HTML源代码如下:

密匙四、Trie树/数据库/倒排索引

Trie树

  适用范围:数据量大,重复多,可是数量系列小可以放入内存
  基本原理及中央:达成格局,节点孩子的意味方法
  增加:压缩完毕。

  难点实例:

  1. 有10个文件,各个文件1G,每种文件的每一行都存放的是用户的query,逐个文件的query都只怕再次。要你根据query的频度排序。
  2. 1000万字符串,其中多少是同一的(重复),要求把重复的满贯去掉,保留没有重新的字符串。请问怎么统筹和兑现?
  3. 检索热门查询:查询串的重复度相比较高,就算总数是1千万,但就算除去重复后,不超越3百万个,每一种不超过255字节。
  4. 上边的第8题:一个文件文件,几乎有一万行,每行一个词,须要计算出其中最频仍出现的前10个词。其化解办法是:用trie树总计每一个词出现的次数,时间复杂度是O(n*le)(le表示单词的平准长度),然后是找出出现最频仍的前10个词。

 

   
越来越多关于Trie树的牵线,请参见此文:从Trie树(字典树)谈到后缀树

数据库索引
  适用范围:大数据量的增删改查
  基本原理及主旨:利用多少的布置落成格局,对海量数据的增删改查举办拍卖。

   
关于数据库索引及其优化,越多可参见此文:http://www.cnblogs.com/pkuoliver/archive/2011/08/17/mass-data-topic-7-index-and-optimize.html。同时,关于MySQL索引背后的数据结构及算法原理,那里还有一篇很好的篇章:http://www.codinglabs.org/html/theory-of-mysql-index.html

倒排索引(Inverted index)
  适用范围:搜索引擎,关键字查询
  基本原理及中央:为什么叫倒排索引?一种索引方法,被用来囤积在全文检索下某个单词在一个文档或然一组文档中的存储地方的映照。
 以英文为例,上边是要被索引的文件:
    T0 = “it is what it is”
    T1 = “what is it”
    T2 = “it is a banana”
    我们就能收获下边的反向文件目录:
   “a”:      {2}
    “banana”: {2}
    “is”:     {0, 1, 2}
   “it”:     {0, 1, 2}
   “what”:   {0, 1}
 检索的条件”what”,”is”和”it”将相应集合的交集。

  正向索引开发出来用来存储每一个文档的单词的列表。正向索引的询问往往知足各种文档有序频繁的全文查询和各种单词在校验文档中的验证那样的询问。在正向索引中,文档占据了中央的岗位,每一个文档指向了一个它所含有的索引项的系列。约等于说文档指向了它包含的那几个单词,而反向索引则是单词指向了蕴藏它的文档,很不难看到那个反向的涉嫌。
  扩展:
  难点实例:文档检索系统,查询那多少个文件包括了某单词,比如大规模的学术故事集的要害字搜索。

   
关于倒排索引的运用,越来越多请参见:第二十三、四章:杨氏矩阵查找,倒排索引关键词Hash不重复编码实践,及第二十六章:基于给定的文档生成倒排索引的编码与履行

<html>
<body>
<input type=”button” id=”btnClose” value=”关闭” />
</body>
</html>
那就是说找出该按钮并为之添加伊夫nt Handler的代码如下:

密匙五、外排序

  适用范围:大数额的排序,去重
  基本原理及中央:外排序的统一措施,置换拔取败者树原理,最优归并树
  扩展:
  难点实例:
  1).有一个1G高低的一个文件,里面每一行是一个词,词的轻重缓急不当先16个字节,内存限制大小是1M。再次来到频数最高的100个词。
  这些数目颇具很让人侧目的表征,词的轻重缓急为16个字节,不过内存唯有1M做hash显明不够,所以可以用来排序。内存可以当输入缓冲区使用。

   
关于多路归并算法及外排序的现实性行使场景,请参见此文:第十章、如何给10^7个数据量的磁盘文件排序

 

密匙六、分布式处理之Mapreduce

      适用范围:数据量大,但是数量连串小可以放入内存
  基本原理及中央:将数据交到不一致的机械去处理,数据划分,结果归约。
  扩展:
  难点实例:

  1. The canonical example application of MapReduce is a process to count
    the appearances of each different word in a set of documents:
  2. 海量数据分布在100台微机中,想个办法高效计算出那批数量的TOP10。
  3. 共计有N个机器,各个机器上有N个数。每一个机器最多存O(N)个数并对它们操作。如何找到N^2个数的中数(median)?

 

   
越多具体阐释请参见:从Hadhoop框架与MapReduce方式中谈海量数据处理,及MapReduce技术的启幕询问与学习

HtmlDocument
htmlDoc = webBrowser.Document;
HtmlElement btnElement = htmlDoc.All[“btnClose”];
if (btnElement != null)
{
     btnElement.click += new
HtmlElementEventHandler(HtmlBtnClose_Click);
}

参考文献

  1. 十道海量数据处理面试题与十个艺术大总括
  2. 海量数据处理面试题集锦与Bit-map详解
  3. 十一、从头到尾彻底解析Hash表算法
  4. 海量数据处理之Bloom
    Filter详解
  5. 从Trie树(字典树)谈到后缀树
  6. 其三章续、Top
    K算法难题的落实
  7. 第十章、怎样给10^7个数据量的磁盘文件排序
  8. 第二十三、四章:杨氏矩阵查找,倒排索引关键词Hash不重复编码实践
  9. 第二十六章:基于给定的文档生成倒排索引的编码与实践
  10. 从Hadhoop框架与MapReduce情势中谈海量数据处理
  11. 第十六~第二十章:全排列,跳台阶,奇偶排序,首个只出现三次等难点
  12. http://blog.csdn.net/v\_JULY\_v/article/category/774945
  13. STL源码剖析第五章,侯捷著。

其中HtmlBtnClose_Click是按下Web按钮时的伊芙nt
Handler。

后记

   
经过地点这么多海量数据处理面试题的空袭,大家照例可以见见那类难点是有必然的缓解方案/方式的,所以,不必将其神化。当然,那类面试题所含有的标题仍旧相比简单的,若你在那上头有越多实践经验,欢迎随时来信与自作者不吝分享:zhoulei0907@yahoo.cn。当然,自会表明分享者及来源。

   
但是,相信您也已经发现到,若单纯论海量数据处理面试题,本blog内的关张一量数据处理面试题的稿子已涵盖了您能在网上所找到的70~80%。但稍事,必须负总责的敬告大家:无论是这一个海量数据处理面试题也好,仍然算法也好,70~80%的人不是倒在这两方面,而是倒在基础之上,所以,无论任什么时候候,基础最重大,没了基础,便什么都不是。最后,推荐外国一面试题网站:http://www.careercup.com/,以及民用正在读的Redis/MongoDB绝佳站点:http://blog.nosqlfan.com/

    OK,本文若有其它难点,欢迎随时不吝留言,评论,赐教,多谢。完。

 

 
  PS:csdn方今始发评选10大博客专栏,投票地址为:http://event.blog.csdn.net/topcolumn/topcolumn.aspx。作者的3个专辑是编程语言栏目中的第1个:经典算法探究http://blog.csdn.net/column/details/Dijkstra.html;第6个:微软面试100题连串http://blog.csdn.net/column/details/ms100.html;第10个:程序员编程艺术http://blog.csdn.net/column/details/taopp.html。 假如你以为本身写的还行,欢迎选我。以后去投票,有时机得到3个月VIP卡,从而免积分下载任何资源。本月尾2012.03.30直到。谢谢。

很简短吗?那么稍稍高级一点的——我们都知晓一个HTML成分只怕有广大形形色色的事件,而HtmlElement这么些类只交给最常用、共通的多少个。那么,

什么样响应其余事件吧?那也很不难,只要求调用HtmlElement的Attach伊芙ntHandler就足以了:

btnElement.AttachEventHandler(“onclick”,
new EventHandler(HtmlBtnClose_Click));
//这一句等价于上边的btnElement.click += new
HtmlElement伊芙ntHandler(HtmlBtnClose_Click);
对此其它事件,把”onclick”换成该事件的名字就足以了。例如:

formElement.AttachEventHandler(“onsubmit”,
new EventHandler(HtmlForm_Submit));

Study
Case 2:表单(form)的机动填写和交给

要使大家的WebBrowser具有自动填表、甚至电动提交的功用,并不困难。

假使有一个最简易的记名页面,输入用户名密码,点“登录”按钮即可登录。已知用户名输入框的id(或Name,下同)是username,密码输入框的id

是password,“登录”按钮的id是submitbutton,那么大家只要求在webBrowser的DocumentCompleted事件中选拔上面的代码即可:

HtmlElement
btnSubmit = webBrowser.Document.All[“submitbutton”];
HtmlElement tbUserid = webBrowser.Document.All[“username”];
HtmlElement tbPasswd = webBrowser.Document.All[“password”];

if
(tbUserid == null || tbPasswd == null || btnSubmit == null)
    return;

tbUserid.SetAttribute(“value”,
“smalldust”);
tbPasswd.SetAttribute(“value”, “12345678”);

btnSubmit.InvokeMember(“click”);
此地大家用SetAttribute来设置文本框的“value”属性,用InvokeMember来调用了按钮的“click”方法。因为不一样的Html成分,其具备的性质和方

法也不尽一致,所以.Net
2.0提供了合并的HtmlElement来概括种种Html成分的还要,提供了那多少个法子以调用元素特有的效应。关于各个Html成分的

属性和办法一览,可以查阅MSDN的DHTML
Reference。

※关于表单的交给,的确还有另一种艺术就是取得form成分而不是button,并用form成分的submit方法:

HtmlElement
formLogin = webBrowser.Document.Forms[“loginForm”];
//……
formLogin.InvokeMember(“submit”);
本文之所以没有推荐那种艺术,是因为前日的网页,很多都在submit按钮上添加onclick事件,以对交付的情节做最焦点的证实。假若一贯利用form的

submit方法,那一个验证代码就得不到实践,有或然会引起错误。

Study Case 3:查找并选用文本

这一次大家愿意完结一个和IE一模一样的检索功用,以对Web页面内的文字举办搜索。

文本查找要凭借TextRange对象的findText方法。不过,.Net里并不曾那些目的。那是因为,.Net
2.0提供的HtmlDocument,HtmlWindow,

HtmlElement等类,只可是是对本来mshtml那么些COM组件的不完全封装,只提供了mshtml的一对作用。所以重重时候,我们照样要器重mshtml来贯彻自个儿

们急需的成效。好在那个.Net类都提供了DomDocument这一个性格,使得大家很不难把.Net对象转换为COM对象使用。上面的代码演示了什么样寻找Web页面

的文本。
(须求添加mshtml的引用,并加上using mshtml;)

    public partial class SearchDemo : Form
     {
        // 建立一个寻找用的TextRange(IHTMLTxtRange接口)
        private IHTMLTxtRange searchRange = null;
        public SearchDemo()
         {
             InitializeComponent();
         }

       
private void btnSearch_Click(object sender, EventArgs e)
         {
            // Document的DomDocument属性,就是该目的内部的COM对象。
             IHTMLDocument2 document =
(IHTMLDocument2)webBrowser.Document.DomDocument;
            string keyword = txtKeyword.Text.Trim();
            if (keyword == “”)
                return;

           
//
IE的追寻逻辑就是,假设有选区,就从当前选区伊始+1字符处初叶查找;没有的话就从页面最初伊始查找。
            //
这一个逻辑其实是有点不大方便的,大家这边并非管,和IE一致即可。
            if (document.selection.type.ToLower() != “none”)
             {
                 searchRange =
(IHTMLTxtRange)document.selection.createRange();
                 searchRange.collapse(true);
                 searchRange.moveStart(“character”, 1);
             }
            else
             {
                 IHTMLBodyElement body =
(IHTMLBodyElement)document.body;
                 searchRange = (IHTMLTxtRange)body.createTextRange();
             }

           
// 若是找到了,就分选(高亮呈现)该重大字;否则弹出音讯。
            if (searchRange.findText(keyword, 1, 0))
             {
                 searchRange.select();
             }
            else
             {
                 MessageBox.Show(“已搜索到文档结尾。”);
             }
         }
     }

到此停止,简单的追寻就化解了。至于替换功用,看了下一个例证,小编深信不疑你就足以触类旁通轻松消除了。

Study Case 4:高亮突显

上一个例证中大家学会了搜寻文本——究跟到底,对Web页面如故只读不写。那么,如若说要把富有的追寻结果高亮呈现呢?大家很快会想到把具备匹

配的文字颜色、背景改一下就可以了。
率先想到的只怕是直接修改HTML文本吧……不过,与SourceCode的高亮呈现不一致,大家须要同时只必要高亮页面中的文本部分。HTML标签、脚本代码

等等是纯属不应该去改变的。由此大家无法把一切页面的Source
Code读进来然后replace,那样有磨损HTML文件结构的只怕;大家只好在能够分离出

文本与其余剧情(标签,脚本……)的前提下举行。

具体方法有很多,上边提供八个相比不难的艺术。

方法一:使用TextRange(IHTMLTxtRange)
有了上一个Case的底子,相信大家立马会想到利用TextRange。没错,TextRange除了提供查找方法之外,还提供了一个pasteHTML方法,以指定的HTML

文件替换当前TextRange中的内容。代码片断如下:

   
public partial class HilightDemo : Form
     {
        // 定义高亮突显效果的标签。
        string tagBefore = “<span
style=’background-color:yellow;color:black’>”;
        string tagAfter = “</span>”;

       
// ……

       
private void btnHilight_Click(object sender, EventArgs e)
         {
             HtmlDocument htmlDoc = webBrowser.Document;
            string keyword = txtKeyword.Text.Trim();
            if (keyword == “”)
                return;

           
object oTextRange = htmlDoc.Body.InvokeMember(“createTextRange”);

            
mshtml.IHTMLTxtRange txtrange = oTextRange as
mshtml.IHTMLTxtRange;

           
while (txtrange.findText(keyword, 1, 4))
             {
                try
                 {
                     txtrange.pasteHTML(tagBefore + keyword +
tagAfter);
                 }
                catch { }
                 txtrange.collapse(false);
             }
         }
     }

※那段代码里取得IHTMLTxtRange的办法和方面的例子稍稍不一样,其实所谓条条大路通赫尔辛基,本质是一致的。

办法二:使用DOM(文档对象模型)
将HTML文档解析为DOM,然后遍历各个节点,在里边搜索关键字并举行对应替换处理即可。

   
public partial class HilightDemo : Form
     {
        //……

       
private void btnHilight_Click(object sender, EventArgs e)
         {
             HTMLDocument document =
(HTMLDocument)webBrowser.Document.DomDocument;
             IHTMLDOMNode bodyNode =
(IHTMLDOMNode)webBrowser.Document.Body.DomElement;
            string keyword = txtKeyword.Text.Trim();
            if (keyword == “”)
                return;

            
HilightText(document, bodyNode, keyword);
         }

       
private void HilightText(HTMLDocument document, IHTMLDOMNode node,
string keyword)
         {
            // nodeType = 3:text节点
            if (node.nodeType == 3)
             {
                string nodeText = node.nodeValue.ToString();
                // 假如找到了关键字
                if (nodeText.Contains(keyword))
                 {
                     IHTMLDOMNode parentNode = node.parentNode;
                    //
将重点字作为分隔符,将文件分离,并一一添加到原text节点的父节点
                    string[] result = nodeText.Split(new string[] {
keyword }, StringSplitOptions.None);
                    for (int i = 0; i < result.Length – 1; i++)
                     {
                        if (result[i] != “”)
                         {
                             IHTMLDOMNode txtNode =
document.createTextNode(result[i]);
                             parentNode.insertBefore(txtNode, node);
                         }
                         IHTMLDOMNode orgNode =
document.createTextNode(keyword);
                         IHTMLDOMNode hilightedNode =
(IHTMLDOMNode)document.createElement(“SPAN”);
                         IHTMLStyle style =
((IHTMLElement)hilightedNode).style;
                         style.color = “black”;
                         style.backgroundColor = “yellow”;
                         hilightedNode.appendChild(orgNode);

                        
parentNode.insertBefore(hilightedNode, node);
                     }
                    if (result[result.Length – 1] != “”)
                     {
                             IHTMLDOMNode postNode =
document.createTextNode(result[result.Length – 1]);
                             parentNode.insertBefore(postNode, node);
                     }
                     parentNode.removeChild(node);
                 } // End of nodeText.Contains(keyword)
             }
            else
             {
                // 即使不是text节点,则递归搜索其子节点
                 IHTMLDOMChildrenCollection childNodes = node.childNodes
as IHTMLDOMChildrenCollection;
                foreach (IHTMLDOMNode n in childNodes)
                 {
                     HilightText(document, n, keyword);
                 }
             }
         }
     }

地方的两段代码都是为了清晰易懂而简单得无法再简的,有不少地方很不周详。比如,没考虑到如何从高亮呈现状态复苏;也远非轻重写匹配等等。

本来,领悟了规律之后相信那些都不会太难。

那三种方法各有利害:
运用TextRange较轻量快捷,而且有一个绝招,就是足以把跨标签(Tag)的第一字挑出来。例如,有这般一段HTML:

<b>Hel</b>lo
World!
先不管小编出于如何目标让Hel三个字母成为粗体,总而言之展将来页面上的是一句“Hello
World!”。在大家期望高亮页面中的“Hello”那一个第一字时

,倘诺用DOM分析的话,会得出含有“Hel”的<b>节点和文件节点“lo
World!”多少个节点,由此不能将其挑出来。而TextRange则能科学识别,将其设

置为高亮。由此也得以说TextRange是只和文件有关,和HTML语法结构无关的靶子。

但是,TextRange也有其致命缺点,加亮不难,反向的话就很难。换句话说,去除高亮展现的时候无法再用TextRange,而急需拔取任何艺术。

而DOM方法则正好相反,
由于DOM的树状结构特征,尽管不能够(或然很难)跨越Tag搜索关键字,不过去除高亮展现并不麻烦。

Study
Case 5:与剧本的互操作

在Case
1当中,大家早就看到,Web页面的HTML成分的事件,可以由Windows
Form端来响应,可以在某种程度上作为是Web页面调用WinForm;那么反过

来,WinForm除了可以一直访问Web页面的HTML成分之外,能不能调用Web页面里的各样Script呢?

首先是调用Web页面的台本中已经定义好的函数。假如HTML中如同下Javascript:

function
DoAdd(a, b) {
    return a + b;
}
那么,大家要在WinForm调用它,只需如下代码即可:

object
oSum = webBrowser.Document.InvokeScript(“DoAdd”, new object[] { 1, 2
});
int sum = Convert.ToInt32(oSum);
其次,即便大家想举办一段Web页面中原本没有的台本,该怎么做吧?这一次.Net的类没有提供,看来还要依赖COM了。IHTMLWindow2可以将随机的字符

串作为脚本代码来施行。

string
scriptline01 = @”function ShowPageInfo() {“;
string scriptline02 = @”      var numLinks = document.links.length; “;
string scriptline03 = @”      var numForms = document.forms.length; “;
string scriptline04 = @”      var numImages = document.images.length;
“;
string scriptline05 = @”      var numScripts = document.scripts.length;
“;
string scriptline06 = @”      alert(‘网页的统计结果:\r\n链接数:’ +
numLinks + “;
string scriptline07 = @”         ‘\r\n表单数:’ + numForms + “;
string scriptline08 = @”         ‘\r\n图像数:’ + numImages + “;
string scriptline09 = @”         ‘\r\n脚本数:’ + numScripts);}”;
string scriptline10 = @”ShowPageInfo();”;

string
strScript = scriptline01 + scriptline02 + scriptline03 + scriptline04 +
scriptline05 +
                    scriptline06 + scriptline07 + scriptline08 +
scriptline09 + scriptline10;

IHTMLWindow2
win = (IHTMLWindow2)webBrowser.Document.Window.DomWindow;
win.execScript(strScript,
“Javascript”);http://www.xmlasp.net/n1670c13.aspx

http://hi.baidu.com/motiansen/blog/item/9e99a518233ca3b24aedbca9.html

采纳ObjectForScripting属性,可启用 WebBrowser 控制项所装载之 Web
网页与分包 WebBrowser 控制项之应用程式间的通信。
本条本性可让您结合动态超文字标记语言 (DHTML)
程式码与用户端应用程式程式码。
指定给那些天性的物件可让 Web 网页指令码做为 window.external
物件,那么些物件是为了存取主应用程式而提供的内建 DOM 物件。

private void btnScriptEvent_Click(object sender, EventArgs e)
{
           webBrowser1.ObjectForScripting = this;

           
string szWebBrowserText = “<html>” +
                “<head>” +
                “<title></title>”+                   
                 “</head>” +
               “<body onkeydown=\”KeyDown()\”
oncontextmenu=\”event.returnValue=false\”>”+
              
               “Please enter your name:<br/>”+
                 “<input type=’text’ name=’Name’/><br/>”+
                 “<font
onClick=’window.external.ClickEvent(Name.value)’>Click
Here</font>”+
                “</body></html>”;

             webBrowser1.DocumentText = szWebBrowserText;
         }
        public void ClickEvent(string userName)
        {
            // Simply echo out the name that the user typed in the input
box of the HTML page
            if
(System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft
== true)
                 MessageBox.Show(“Hello ” + userName, “Managed Web
Browser Sample”, MessageBoxButtons.OK,

MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign |
MessageBoxOptions.RtlReading);
            else
                 MessageBox.Show(“Hello ” + userName, “Managed Web
Browser Sample”, MessageBoxButtons.OK,

MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1);

        
}

 

=
szWebBrowserText;

==================================
丰裕类型 条件
ArgumentException
设置该属性时指定的值为非公共类型的实例。


或 –

设置该属性时指定的值为非
COM 可知的档次的实例。有关越多音讯,请参见
马尔斯hal.IsTypeVisibleFromCom。

备注
使用该属性启用 WebBrowser 控件承载的网页与分包 WebBrowser
控件的应用程序之间的通讯。使用该属性可以将动态 HTML (DHTML)
代码与客户端

应用程序代码集成在联名。为该属性指定的对象可作为
window.external 对象(用于主机访问的放权 DOM 对象)用于网页脚本。

可以将此属性设置为愿意其公共性质和方法可用于脚本代码的其余COM 可知的目的。可以经过行使 ComVisibleAttribute
对类举行标记使其变为

COM
可知的类。

若要从客户端应用程序代码调用网页中定义的函数,请使用可从
Document 属性检索的 HtmlDocument 对象的 HtmlDocument.InvokeScript
方法。

示例
上面的代码示例演示怎么样运用 ObjectForScripting
属性。在该示例中,ObjectForScripting 属性被安装为近来窗体。


using
System;
using System.Windows.Forms;
using System.Security.Permissions;

[PermissionSet(SecurityAction.Demand,
Name=”FullTrust”)]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class Form1 : Form
{
    private WebBrowser webBrowser1 = new WebBrowser();
    private Button button1 = new Button();

   
[STAThread]
    public static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form1());
    }

   
public Form1()
    {
        button1.Text = “call script code from client code”;
        button1.Dock = DockStyle.Top;
        button1.Click += new EventHandler(button1_Click);
        webBrowser1.Dock = DockStyle.Fill;
        Controls.Add(webBrowser1);
        Controls.Add(button1);
        Load += new EventHandler(Form1_Load);
    }

   
private void Form1_Load(object sender, EventArgs e)
    {
        webBrowser1.AllowWebBrowserDrop = false;
        webBrowser1.IsWebBrowserContextMenuEnabled = false;
        webBrowser1.WebBrowserShortcutsEnabled = false;
        webBrowser1.ObjectForScripting = this;
        // Uncomment the following line when you are finished
debugging.
        //webBrowser1.ScriptErrorsSuppressed = true;

       
webBrowser1.DocumentText =
            “<html><head><script>” +
            “function test(message) { alert(message); }” +
            “</script></head><body><button ” +
            “onclick=\”window.external.Test(‘called from script
code’)\”>” +
            “call client code from script code</button>” +
            “</body></html>”;
    }

   
public void Test(String message)
    {
        MessageBox.Show(message, “client code”);
    }

   
private void button1_Click(object sender, EventArgs e)
    {
        webBrowser1.Document.InvokeScript(“test”,
            new String[] { “called from client code” });
    }

}


// Navigates to the URL in the address box when
// the ENTER key is pressed while the ToolStripTextBox has focus.
private void toolStripTextBox1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
    {
        Navigate(toolStripTextBox1.Text);
    }
}

//
Navigates to the URL in the address box when
// the Go button is clicked.
private void goButton_Click(object sender, EventArgs e)
{
    Navigate(toolStripTextBox1.Text);
}

//
Navigates to the given URL if it is valid.
private void Navigate(String address)
{
    if (String.IsNullOrEmpty(address)) return;
    if (address.Equals(“about:blank”)) return;
    if (!address.StartsWith(“http://”) &&
        !address.StartsWith(“https://”))
    {
        address = “http://” + address;
    }
    try
    {
        webBrowser1.Navigate(new Uri(address));
    }
    catch (System.UriFormatException)
    {
        return;
    }
}

//
Updates the URL in TextBoxAddress upon navigation.
private void webBrowser1_Navigated(object sender,
    WebBrowserNavigatedEventArgs e)
{
    toolStripTextBox1.Text = webBrowser1.Url.ToString();
}

====================================================================================
HtmlElement.DomElement 属性
属性值
要素的 COM IUnknown 指针,可以将其挟持转换为 HTML
成分接口中的某一个接口,如 IHTMLElement。
备注
HtmlElement 为 Internet Explorer 文档对象模型 (DOM)
的卷入,它是用组件对象模型 (COM) 编写而成。借使急需拜访基础 COM
接口中的未公开

性能或方法(如
IHTMLElement),可以运用此目的查询它们。

为了采纳非托管接口,要求将
MSHTML 库 (mshtml.dll) 导入到应用程序中。然则,也足以应用 Invoke
方法执行未公开属性和方法。

示例
上边的代码示例使用非托管接口获取当前选定的公文,并拔取由用户选拔的 URL
将其更换为超链接。编写此代码时,假定窗体拥有一个名为

WebBrowser1
的 WebBrowser 控件,并假定已经以引用的花样将非托管 MSHTML
库添加到花色中。

C#
复制代码
private void CreateHyperlinkFromSelection()
{
    if (webBrowser1.Document != null)
    {

       
mshtml.IHTMLDocument2 iDoc =
(mshtml.IHTMLDocument2)webBrowser1.Document.DomDocument;

       
if (iDoc != null)
        {
            mshtml.IHTMLSelectionObject iSelect = iDoc.selection;
            if (iSelect == null)
            {
                MessageBox.Show(“Please select some text before using
this command.”);
                return;
            }

           
mshtml.IHTMLTxtRange txtRange =
(mshtml.IHTMLTxtRange)iSelect.createRange();

           
// Create the link.
            if (txtRange.queryCommandEnabled(“CreateLink”))
            {
                Object o = null;
                txtRange.execCommand(“CreateLink”, true, o);
            }
        }
    }
}

http://msdn.microsoft.com/zh-cn/library/system.windows.forms.htmlelement.domelement(VS.80).aspx

===========================================================
使用webbrowser和mshtml.dll获取网页源代码的题材
悬赏分:100 – 化解岁月:2006-7-19 16:52
我使用C#做一个先后,其中提到到一个成效,在输入指定网址之后,需求得到html源代码举行分析。
自家使用了webbrowser控件和mshtml.dll
可是只可以取得到平日页面的源代码
万一采集带有cookie控制的页面就会破产。
哪个人能帮支持?

本人对此webbrowser的选拔并不很清楚,这些空间是或不是能平素获得html代码呢?
mshtml.dll说是可以对html代码举办分析。但哪些选拔?

有哪个人能给出表明和源代码,感谢不尽。
标题补充:小编动用以下代码获取webbrowser中的html,不过有个很意外的题材。作者每一遍点完按钮都会发现文本框中浮现的html都不全,而且都把同一

页面的html突显了不少遍。即使页面内容较大则会挑起程序死掉。
缘何吧?
提问者: willgo – 助理 二级 最佳答案
private void button1_Click(object sender, System.EventArgs e) {
object
url=\”http://www.google.com\\“;
object nothing=null;
this.axWebBrowser1.Navigate2(ref url,ref nothing,ref nothing,ref
nothing,ref nothing);
this.axWebBrowser1.DownloadComplete+=new
System.EventHandler(this.button2_Click);
}

private
void button2_Click(object sender, System.EventArgs e) {
this.textBox1.Text=\”\”;
mshtml.IHTMLDocument2
doc=(mshtml.IHTMLDocument2)this.axWebBrowser1.Document;
mshtml.IHTMLElementCollection all=doc.all;
System.Collections.IEnumerator enumerator=all.GetEnumerator();
while(enumerator.MoveNext() && enumerator.Current!=null)
{
mshtml.IHTMLElement element=(mshtml.IHTMLElement)(enumerator.Current);
if(this.checkBox1.Checked==true)
{
this.textBox1.Text+=\”\\r\\n\\r\\n\”+element.innerHTML;
}
else
{
this.textBox1.Text+=\”\\r\\n\\r\\n\”+element.outerHTML;
}
}
}

=============
留神
本例程中行使了一个未公开的GUID,其在今后的系统中可以生出转移。

  1、定义
IOleCommandTarget 接口

  为定义一个.NET接口以博取有关一个COM接口的参考,请遵从下列步骤:

  1)
赋予.NET接口相应的COM接口的GUID值;

  2)
包罗对接口中存有办法的档次申明;

  3)
包罗对Mshtml.dll和Shdocvw.dll文件的参考,在Visual C#
.NET工程中操作,请听从:

  A.
在类型菜单下单击“添加引用”;

  B.
单击“COM” 选项卡;

  C.
双击“Microsoft HTML Object Library” 和“Microsoft Internet Controls”。

转:http://www.360doc.com/content/10/1006/12/3722251_58785246.shtml

发表评论

电子邮件地址不会被公开。 必填项已用*标注