c++面试题【转】
语言部分:
- 虚函数,多态。这个概念几乎是必问。
- STL的使用和背后数据结构,vector string map set 和hash_map,hash_set
- 实现一个栈类,类似STL中的栈。这个题目初看非常简单,当时我还有点不屑,怎么出这么简单的题。但写过c++和没有写过c++的人写出的代码是一眼就能看出差别的。譬如三大函数有没有写,引用的使用,都非常的关键。如果这方面没有经验,建议阅读下http://book.douban.com/subject/1971825/ 这本书中简单数据结构的实现,细节很关键
- c部分:函数指针的声明
- c++中的多线程
算法部分:
- 判断一个单链表是否存在循环(快慢指针的方法)
- 如何判断一副麻将牌胡了(回朔法)
- 二叉搜索树,节点上已经标有数字,如何找两个节点的最小公共节点(查找第一个在两个节点值中间的节点,如两个节点分别是3,8,查找在3,8之间的值的节点,如没找到,则3,8其中一个是另一个父节点)
- 二叉树,如何找两个节点的最小公共节点(比较笨的方法是,找到从root到两个节点的路径,然后两条路径的从root开始的最后一个相同节点就是所求节点。精妙点的参考lca算法)
- 最短摘要生成,有一个数组,还有一个集合,在数组中寻找包含集合中全部元素的最短子串。详细可以参见编程之美3.5
- 寻找最大的K个数,编程之美2.5
- 如何判断两个网页的相关性(如果说面试搜索相关的只是,看下吴军的数学之美大有裨益,其中的向量空间模型非常优美,TF和IDF这些术语也必须知道)
- Hash的平均查找长度和装填因子的关系(好好回味下数据结构书吧)哈希表(等概率情况下)查找成功与查找不成功的平均查找长度
- 装填因子load factor λ:散列表中元素 与 散列表大小 的比值。
- 常数时间 执行插入 删除 查找,;哈希函数;解决冲突:分离链接法,λ≈1,不使用分离连接,尽量让λ<0.5 这样效率最高
- 一致性hash原理一致性哈希算法(consistent hashing)
- rehash的时候可能导致插入的元素响应时间特别长,有无更好的方法?
- 可以参考redis的rehash实现,当到了rehash的时候,不是一次性把所有的数据迁移到另一个更大的hash表中,而是每次迁移一个bucket,这样可以平摊时间
- 如何对全是01的文件进行压缩,一直没有好的答案。高压缩文件是如何实现的
系统设计部分:
- 当系统的处理请求时间一定的时候,如何可以加快响应速度。(cache的使用),当时很傻,竟然没想到这个,我给的答案是增加系统规模,这样只能减少请求等待时间。有时候面试人就会短路,google的题,想了半天才想出来
- 两块虚拟网卡进行通讯,但是需要数据加密,如何实现数据加密。感觉跟ssl很像
编程部分:
- 二分查找(频率超高)
- 建堆,顺便说下建堆的时间复杂度是O(n),不是log,证明可以看算法导论构建二叉堆时间复杂度的证明
- 写一个函数,将字符串反转,反转方式如下:“I am a student”反转成“student a am I”,不借助任何库函数 (频率超高的一题,先反转整个字符串,然后反转每个词)
详细分析
2.标准关联容器set, multiset, map, multimap
内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-BlackTree)。RB树的统计性能要好于一般的平衡二叉树
3.STL map和set的使用中不易理解的地方
- map: type pair<constKey, T>
- set: type const Key
(1)为何map和set的插入删除效率比用其他序列容器高?,树答:因为对于关联容器来说,不需要做内存拷贝和内存移动。说对了,确实如此。map和set容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点(2)为何每次insert之后,以前保存的iterator不会失效?答:iterator这里就相当于指向节点的指针,内存没有变,指向内存的指针怎么会失效呢(当然被删除的那个元素本身已经失效了)。相对于vector来说,每一次删除和插入,指针都有可能失效,调用push_back在尾部插入也是如此。因为为了保证内部数据的连续存放,iterator指向的那块内存在删除和插入过程中可能已经被其他内存覆盖或者内存已经被释放了。即使时push_back的时候,容器内部空间可能不够,需要一块新的更大的内存,只有把以前的内存释放,申请新的更大的内存,复制已有的数据元素到新的内存,最后把需要插入的元素放到最后,那么以前的内存指针自然就不可用了。特别时在和find等算法在一起使用的时候,牢记这个原则:不要使用过期的iterator。(3)为何map和set不能像vector一样有个reserve函数来预分配数据?答:我以前也这么问,究其原理来说时,引起它的原因在于在map和set内部存储的已经不是元素本身了,而是包含元素的节点。也就是说map内部使用的Alloc并不是map<Key, Data, Compare, Alloc>声明的时候从参数中传入的Alloc。
4.set, multiset
set和multiset会根据特定的排序准则自动将元素排序,set中元素不允许重复,multiset可以重复。因为是排序的,所以set中的元素不能被修改,只能删除后再添加。向set中添加的元素类型必须重载<操作符用来排序。排序满足以下准则:
- 非对称,若A<B为真,则B<A为假。
- 可传递,若A<B,B<C,则A<C。
- A<A永远为假。
set中判断元素是否相等:if(!(A<B || B<A)),当A<B和B<A都为假时,它们相等。
5.map,multimap
map和multimap将key和value组成的pair作为元素,根据key的排序准则自动将元素排序,map中元素的key不允许重复,multimap可以重复。
- map<key,value>
因为是排序的,所以map中元素的key不能被修改,只能删除后再添加。key对应的value可以修改。向map中添加的元素的key类型必须重载<操作符用来排序。排序与set规则一致。
6. List的功能方法
实际上有两种List: 一种是基本的ArrayList,其优点在于随机访问元素,另一种是更强大的LinkedList,它并不是为快速随机访问设计的,而是具有一套更通用的方法。List : 次序是List最重要的特点:它保证维护元素特定的顺序。List为Collection添加了许多方法,使得能够向List中间插入与移除元素(这只推荐LinkedList使用。)一个List可以生成ListIterator,使用它可以从两个方向遍历List,也可以从List中间插入和移除元素。
ArrayList : 由数组实现的List。允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。ListIterator只应该用来由后向前遍历ArrayList,而不是用来插入和移除元素。因为那比LinkedList开销要大很多。LinkedList : 对顺序访问进行了优化,向List中间插入与删除的开销并不大。随机访问则相对较慢。(使用ArrayList代替。)还具有下列方法:addFirst(), addLast(), getFirst(),getLast(), removeFirst() 和 removeLast(), 这些方法 (没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用
7.1 hash_map和map的区别在哪里?
构造函数。hash_map需要hash函数,等于函数;map只需要比较函数(小于函数).存储结构。hash_map采用hash表存储,map一般采用红黑树(RB Tree)实现。因此其memory数据结构是不一样的。
7.2 什么时候需要用hash_map,什么时候需要用map?
总体来说,hash_map 查找速度会比map快,而且查找速度基本和数据数据量大小,属于常数级别map的查找速度是log(n)级别。并不一定常数就比log(n)小,hash还有hash函数的耗时,明白了吧,如果你考虑效率,特别是在元素达到一定数量级时,考虑考虑hash_map。但若你对内存使用特别严格,希望程序尽可能少消耗内存,那么一定要小心,hash_map可能会让你陷入尴尬,特别是当你的hash_map对象特别多时,你就更无法控制了,而且hash_map的构造速度较慢。
8.一些使用上的建议:
Level 1 - 仅仅作为Map使用:采用静态数组Level 2 - 保存定长数据,使用时也是全部遍历:采用动态数组(长度一开始就固定的话静态数组也行)Level 3 - 保存不定长数组,需要动态增加的能力,侧重于寻找数据的速度:采用vectorLevel 3 - 保存不定长数组,需要动态增加的能力,侧重于增加删除数据的速度:采用listLevel 4 - 对数据有复杂操作,即需要前后增删数据的能力,又要良好的数据访问速度:采用dequeLevel 5 - 对数据中间的增删操作比较多:采用list,建议在排序的基础上,批量进行增删可以对运行效率提供最大的保证Level 6 - 上述中找不到适合的:组合STL容器或者自己建立特殊的数据结构来实现
9.其他
(1).vector - 会自动增长的数组vector<int>vec(10) //一个有10个int元素的容器vector<float> vec(10, 0.5)//一个有10个float元素的容器,并且他们得值都是0.5vector<int>::iterator iter;for(iter = vec.begin(); iter != vec.end(); iter++){//. . . . . . .}
vector由于数组的增长只能向前,所以也只提供了后端插入和后端删除,也就是push_back和pop_back。当然在前端和中间要操作数据也是可以的,用insert和erase,但是前端和中间对数据进行操作必然会引起数据块的移动,这对性能影响是非常大的。
最大的优势就是随机访问的能力。vector<T1>::iterator相关的方法有:
begin():用来获得一个指向vector第一个元素的指针end():用来获得一个指向vector最后一个元素之后的那个位置的指针,注意不是指向最后一个元素。erase(vector<T1>::iterator):用来删除作为参数所传入的那个iterator所指向的那个元素。
(2).list - 擅长插入删除的链表list<string>Milkshakes; list<int> Scores;push_back, pop_backpush_front. pop_frontlist是一个双向链表的实现。为了提供双向遍历的能力,list要比一般的数据单元多出两个指向前后的指针一个使用iterator来删除元素的例子list<string> stringList;list<string>::iterator iter;advance(iter, 5); //将iterator指向stringList的第五个元素stringList.erase(iterator);//删除那么删除操作进行以后,传入erase()方法的iterator指向哪里了呢?它指向了删除操作前所指向的那个元素的后一个元素。
(3).deque - 拥有vector和list两者优点的双端队列
(4).这三个模板的总结 比较和一般使用准则
这三个模板都属于序列类模板,可以看到他们有一些通用方法
- size():得到容器大小
- begin():得到指向容器内第一个元素的指针(这个指针的类型依容器的不同而不同)
- end():得到指向容器内最后一个元素之后一个位置的指针
- erase():删除传入指针指向的那个元素
- clear():清除所有的元素
- ==运算符:判断两个容器是否相等
- =运算符:用来给容器赋值
上面的三个模板有各自的特点
- vector模板的数据在内存中连续的排列,所以随机存取元素(即通过[]运算符存取)的速度最快,这一点和数组是一致的。同样由于它的连续排列,所以它在除尾部以外的位置删除或添加元素的速度很慢,在使用vector时,要避免这种操作。
- list模板的数据是链式存储,所以不能随机存取元素。它的优势在于任意位置添加 删除元素的速度。
- deque模板是通过链接若干片连续的数据实现的,所以均衡了以上两个容器的特点
c++面试题【转】的更多相关文章
- .NET面试题系列[8] - 泛型
“可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用.“ - Jon Skeet .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] ...
- 关于面试题 Array.indexof() 方法的实现及思考
这是我在面试大公司时碰到的一个笔试题,当时自己云里雾里的胡写了一番,回头也曾思考过,最终没实现也就不了了之了. 昨天看到有网友说面试中也碰到过这个问题,我就重新思考了这个问题的实现方法. 对于想进大公 ...
- 对Thoughtworks的有趣笔试题实践
记得2014年在网上看到Thoughtworks的一道笔试题,当时觉得挺有意思,但是没动手去写.这几天又在网上看到了,于是我抽了一点时间写了下,我把程序运行的结果跟网上的答案对了一下,应该是对的,但是 ...
- 从阿里巴巴笔试题看Java加载顺序
一.阿里巴巴笔试题: public class T implements Cloneable { public static int k = 0; public static T t1 = new T ...
- JAVA面试题
在这里我将收录我面试过程中遇到的一些好玩的面试题目 第一个面试题:ABC问题,有三个线程,工作的内容分别是打印出"A""B""C",需要做的 ...
- C++常考面试题汇总
c++面试题 一 用简洁的语言描述 c++ 在 c 语言的基础上开发的一种面向对象编程的语言: 应用广泛: 支持多种编程范式,面向对象编程,泛型编程,和过程化编程:广泛应用于系统开发,引擎开发:支持类 ...
- .NET面试题系列[4] - C# 基础知识(2)
2 类型转换 面试出现频率:主要考察装箱和拆箱.对于有笔试题的场合也可能会考一些基本的类型转换是否合法. 重要程度:10/10 CLR最重要的特性之一就是类型安全性.在运行时,CLR总是知道一个对象是 ...
- 我们公司的ASP.NET 笔试题,你觉得难度如何
本套试题共8个题,主要考察C#面向对象基础,SQL和ASP.NET MVC基础知识. 第1-3题会使用到一个枚举类,其定义如下: public enum QuestionType { Text = , ...
- 我设计的ASP.NET笔试题,你会多少呢
本笔试题考查范围包括面向对象基础.HTML.CSS.JS.EF.jQuery.SQL.编码思想.算法等范围. 第1题:接口和抽象类有何区别? 第2题:静态方法和实例方法有何区别? 第3题:什么是多态? ...
- 猫哥网络编程系列:详解 BAT 面试题
从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...
随机推荐
- js日期操作时间看板
var nowTime = null;//获取服务器时间function GetTime() { $.ajax({ url:config._domain + "/AjaxAuctionCen ...
- 12款免费与开源的NoSQL数据库
Naresh Kumar是位软件工程师与热情的博主,对于编程与新事物拥有极大的兴趣,非常乐于与其他开发者和程序员分享技术上的研究成果.近日,Naresh撰文谈到了12款知名的免费.开源NoSQL数据库 ...
- Spring第二天
Spring第二天 整体课程安排(3天+2天): 第一天:Spring框架入门.IoC控制反转的配置管理.Spring Web集成.Spring Junit集成. 第二天:Spring AOP面向切面 ...
- Android Studio Gradle project refresh failed No such property classpath for class
新建的一个 android 项目居然发现不能运行,gradle 无法启动,奇怪: Gradle 'Meitian' project refresh failed: No such p ...
- HDU2124 Repair the Wall(贪心)
Problem Description Long time ago , Kitty lived in a small village. The air was fresh and the scener ...
- 2、使用Struts2实现登录功能(没有连接数据)
1.创建如下的目录结构 2.在com.entity包下创建 package com.entity; /** * 用户类 * @author Holly老师 * */ public class User ...
- C#读取和写入文件
一.读取文件 如果你要读取的文件内容不是很多, 可以使用 File.ReadAllText(FilePath) 或指定编码方式 File.ReadAllText(FilePath, Encoding) ...
- Binary Trees
1. Definiation What is Binary Trees? Collection of node (n>=0) and in which no node can have more ...
- 从零开始学Axure原型设计(进阶篇)
Axure不仅能制作静态的视觉稿.页面,还能添加交互动作,是进行原型设计的最佳软件之一.在认识了Axure的界面和部件库之后,我们可以用它来画线框图了,但是静态的线框图在表达上不如有交互的原型图来得直 ...
- idea 切换新项目 新窗口 原窗口
选择 file--setting. 在新打开的窗口中选择 Appearance & Behavior--System Settings 点 Confirm window to open pro ...