面试题解答及记录

来源:互联网 发布:留学低龄化数据 编辑:程序博客网 时间:2024/04/30 08:10

题目来源于互联网以及自己的经历,由于互联网的来源实在太多,没有一一标记,再次感谢曾经面试而分享的人

1.HTTP协议

/*Answer:超文本传送协议定义了浏览器怎样向万维网服务器请求万维网文档,以及服务器怎样把文档传送给浏览器。HTTP是面向事务的应用层协议,能够在万维网上可靠地交换文件(文本、声音、视频等)万维网工作过程|<---建立TCP连接---->|(TCP 80端口)|----HTTP请求报文--->||<---HTTP响应报文----||<---释放TCP连接---->|(1)HTTP无连接HTTP使用了面向连接的TCP作为传输层协议,保证了数据的可靠性。HTTP不必考虑数据在传送过程中被丢弃了怎样重传。但是HTTP本身是无连接的,虽然使用了TCP,但通信双方在交换HTTP报文前不需要先建立HTTP连接。(2)HTTP无状态同一个客户第二次访问同一个服务器的一个页面时,服务器的响应和第一次相同的。(可以使用cookie解决无状态)(3)状态码每一个请求报文后都能收到一个响应报文(HTTP版本,状态码,解析状态码简单短语)1xx表示通知消息2xx表示成功3xx表示重定向4xx表示客户差错(403Forbidden服务器已经理解请求,但是拒绝执行它;404Not Found:请求失败,请求所希望得到的资源未被在服务器上发现)5xx表示服务器差错(502Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。)(4)文档类型静态文档和动态文档(访问服务器时才由应用程序动态创建的)*/

2.linux网络编程的c/s通信流程

UNIX网络编程里的TCP11种状态转移,也可以表达通信流程




3.模板与特化

特化我当时还真是忘了,因为项目开发中没有使用到,关注也就少了,果然基础很重要

为什么需要特化呢?

/*首先就是不可能写出对所有实例化的类型都合适的模版,某些情况下通用的模块对有些类型可能完全是错误的;基于上面的原因所以会时常需要进行模块特化操作。*/template <typename T>int compare(const T & x, const T & y){    if (x < y) return -1;    if (y < x) return 1;    return 0;}//例如这个例子,对于C字符串,比较的结果就完全是错误的
特化的三种类型转自:http://www.cnblogs.com/kyleada/archive/2011/05/23/2054479.htm

/**********************

特化的三种类型:

(1)特化为绝对类型(2)特化为引用/指针类型(3)特化为另一个类模板***********************///普遍形式template<class T>class Compare{public:static bool IsEqual(const T& lh,const T& rh){return lh==rh;}};//(1)特化为绝对类型//为float特化template<>class Compare<float>{public:static bool IsEqual(const T& lh,const T& rh){return abs(lh-rh)<10e-3;}};//(2)特化为引用/指针类型(iterator_traits)template<class _Iterator>struct iterator_traits{//迭代器相应型别最常用的有五种://分别是value_type,difference_type,reference,pointer,iterator_categorytypedef typename _Iterator::iterator_category iterator_category;typedef typename _Iterator::value_type        value_type;typedef typename _Iterator::difference_type   difference_type;typedef typename _Iterator::pointer           pointer;typedef typename _Iterator::reference         reference;};//为_Tp*特化template<class _Tp>struct iterator_traits<_Tp*>{typedef random_access_iterator_tag iterator_category;typedef _Tp                         value_type;typedef ptrdiff_t                   difference_type;typedef _Tp*                        pointer;typedef _Tp&                        reference;};//除了T*, 我们也可以将T特化为 const T*, T&, const T&等//IsEqual特化T*template<class T>class Compare<T*>{public:    static bool IsEqual(const T* lh, const T* rh)    {        return Compare<T>::IsEqual(*lh, *rh);    }};//这种特化其实是就不是一种绝对的特化, 它只是对类型做了某些限定//但仍然保留了其一定的模板性,这种特化给我们提供了极大的方便。//如这里, 我们就不需要对int*, float*, double*等等类型分别做特化了。//(3)特化为另外一个类模板//这其实是第二种方式的扩展,其实也是对类型做了某种限定,而不是绝对化为某个具体类型//为vector<T>特化template<class T>class Compare<vector<T>>{public:    static bool IsEqual(const vector<T>& lh, const vector<T>& rh)    {        if(lh.size() != rh.size()) return false;        else        {            for(int i = 0; i < lh.size(); ++i)            {                if(lh[i] != rh[i]) return false;            }        }        return true;    }};//这就把IsEqual的参数限定为一种vector类型, 但具体是vector<int>还是vector<float>, 我们可以不关心,//因为对于这两种类型,我们的处理方式是一样的,我们可以把这种方式称为“半特化”。

4.动态规划的思想

//动态规划算法的基本思想//摘自:http://www.cnblogs.com/lvpengms/archive/2010/02/03/1663055.html/*动态规划算法的基本思想是:将待求解的问题分解成若干个相互联系的子问题,先求解子问题,然后从这些子问题的解得到原问题的解;对于重复出现的子问题,只在第一次遇到的时候对它进行求解,并把答案保存起来,让以后再次遇到时直接引用答案,不必重新求解。动态规划算法将问题的解决方案视为一系列决策的结果,与贪婪算法不同的是,在贪婪算法中,每采用一次贪婪准则,便做出一个不可撤回的决策;而在动态规划算法中,还要考察每个最优决策序列中是否包含一个最优决策子序列,即问题是否具有最优子结构性质。动态规划算法的有效性依赖于待求解问题本身具有的两个重要性质:(1)最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。(2)子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简 单地查看一下结果,从而获得较高的解题效率。动态规划算法步骤:(1)分析问题的最优解,找出最优解的性质,并刻画其结构特征;(2)递归地定义最优值;(3)采用自底向上的方式计算问题的最优值;(4)根据计算最优值时得到的信息,构造最优解。*///动态规划和贪心算法的区别//摘自http://zhidao.baidu.com/link?url=NsRMilVf06xD6W4G6r2GA-Wg95cxn0Wb7UsAgyxz_bwJ7z6Px6b10r7iVcYsy7ZhwbafyxCM6kT0KXUDbtb3hq/*相同点:动态规划和贪心算法都是一种递推算法 均有局部最优解来推导全局最优解 不同点: 贪心算法: (1)贪心算法中,作出的每步贪心决策都无法改变,因为贪心策略是由上一步的最优解推导下一步的最优解,而上一步之前的最优解则不作保留。 (2)由(1)中的介绍,可以知道贪心法正确的条件是:每一步的最优解一定包含上一步的最优解。 动态规划算法: (1)全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解,因此需要记录之前的所有最优解 (2)动态规划的关键是状态转移方程,即如何由以求出的局部最优解来推导全局最优解 (3)边界条件:即最简单的,可以直接得出的局部最优解*///从问题树看异同//摘自;http://blog.csdn.net/jarvischu/article/details/6056387/*最优解问题大部分都可以拆分成一个个的子问题,把解空间的遍历视作对子问题树的遍历,则以某种形式对树整个的遍历一遍就可以求出最优解。贪心和动态规划本质上是对子问题树的一种修剪。两种算法要求问题都具有的一个性质就是“子问题最优性”。即,组成最优解的每一个子问题的解,对于这个子问题本身肯定也是最优的。如果以自顶向下的方向看问题树(原问题作为根),则我们每次只需要向下遍历代表最优解的子树就可以保证会得到整体的最优解。形象一点说,可以简单的用一个值(最优值)代表整个子树,而不用去求出这个子树所可能代表的所有值。动态规划方法代表了这一类问题的一般解法。我们自底向上(从叶子向根)构造子问题的解,对每一个子树的根,求出下面每一个叶子的值,并且以其中的最优值作为自身的值,其它的值舍弃。动态规划的代价就取决于可选择的数目(树的叉数)和子问题的的数目(树的节点数,或者是树的高度)。贪心算法是动态规划方法的一个特例。贪心特在,可以证明,每一个子树的根的值不取决于下面叶子的值,而只取决于当前问题的状况。换句话说,不需要知道一个节点所有子树的情况,就可以求出这个节点的值。通常这个值都是对于当前的问题情况下,显而易见的“最优”情况。因此用“贪心”来描述这个算法的本质。由于贪心算法的这个特性,它对解空间树的遍历不需要自底向上,而只需要自根开始,选择最优的路,一直走到底就可以了。这样,与动态规划相比,它的代价只取决于子问题的数目,而选择数目总为1。*///找钱问题/*现只有面额为 11元、5元、1元的三种人民币。给定一个 数目为 money 的人民币,如何用这三种面额的人民币 找开它,且用的人民币张数最少    如:给定 10元,我们可以有以下找法:2张  5元面额        1张  5元面额+5张1元面额        10张 1元面额      我们 选择第一种找法。只用2张人民币。//代码实现:http://blog.csdn.net/jarvischu/article/details/6056963如果现在要找开 15元钱,则        1. 根据动态规划法的解题思想,得到最优解为3张5元面额的,总共3张        2. 根据贪心算法的解题思想,得到的近似最优解为1张11元面额的加上4张1元面额的,总共 5张*///个人理解://能用贪心的一定能用动态规划//如果在动态规划中找到一个最优解的迭代公式可以满足贪心的要求,普通的动态规划变成贪心










0 0
原创粉丝点击