腾讯电话面试记录与总结
前日和腾讯公司约好了一个电话面试,第一次面试就是腾讯,不得不说有点浪费机会,因为第一次面试总是惨淡收尾。不过我还是一早就准备了,一直到晚上等到了腾讯的电话,大概晚上八点半开始面试,面试时间大概为半个小时,面试完感觉身体被掏空。第一次面试感觉很多地方表现的不好,满分十分,给自己打个及格分吧。以下是对电话面试内容的一些总结,查漏补缺,路漫漫其修远兮。
面试过程大概是面试官以你的简历出发,然后以你的项目为主线向四周伸展知识点。这也是我第一次向别人介绍我的项目,回想起来感觉语言组织的不是很好,可能以后要注意。面试的大概问题为以下几种,作为笔记也记录一下相关问题的答案。
1.项目中数据库采用的类型?mysql;有没有考虑别的数据库?MongoDB
有关mysql和Mongo的区别记录如下:
MySQL是关系型数据库。优势:在不同的引擎上有不同 的存储方式。
查询语句是使用传统的sql语句,拥有较为成熟的体系,成熟度很高。
开源数据库的份额在不断增加,mysql的份额也在持续增长。
缺点:在海量数据处理的时候效率会显著变慢。
Mongodb是非关系型数据库(nosql ),属于文档型数据库。文档是mongoDB中数据的基本单元,类似关系数据库的行,多个键值对有序地放置在一起便是文档,语法有点类似javascript面向对象的查询语言,它是一个面向集合的,模式自由的文档型数据库。
存储方式:虚拟内存+持久化。
查询语句:是独特的Mongodb的查询方式。
适合场景:事件的记录,内容管理或者博客平台等等。
架构特点:可以通过副本集,以及分片来实现高可用。
数据处理:数据是存储在硬盘上的,只不过需要经常读取的数据会被加载到内存中,将数据存储在物理内存中,从而达到高速读写。
成熟度与广泛度:新兴数据库,成熟度较低,Nosql数据库中最为接近关系型数据库,比较完善的DB之一,适用人群不断在增长。
优点:快速!在适量级的内存的Mongodb的性能是非常迅速的,它将热数据存储在物理内存中,使得热数据的读写变得十分快。高扩展性,存储的数据格式是json格式!
缺点:不支持事务,而且开发文档不是很完全,完善。
关于MongoDB与Mysql的对比:
mongodb与mysql命令对比 传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,
MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。
MongoDB对于关系型数据库里的表,但是集合中没有列、行和关系概念,这体现了模式自由的特点。
你期望一个更高的写负载
默认情况下,对比事务安全,MongoDB更关注高的插入速度。如果你需要加载大量低价值的业务数据,那么MongoDB将很适合你的用例。但是必须避免在要求高事务安全的情景下使用MongoDB,比如一个1000万美元的交易。
设置副本集(主-从服务器设置)不仅方便而且很快,此外,使用MongoDB还可以快速、安全及自动化的实现节点(或数据中心)故障转移。
未来会有一个很大的规模
数据库扩展是非常有挑战性的,当单表格大小达到5-10GB时,MySQL表格性能会毫无疑问的降低。如果你需要分片并且分割你的数据库,MongoDB将很容易实现这一点。
使用基于位置的数据查询
MongoDB支持二维空间索引,因此可以快速及精确的从指定位置获取数据。
非结构化数据的爆发增长
给RDBMS (Relational Database Management System 关系数据库管理系统)增加列在有些情况下可能锁定整个数据库,或者增加负载从而导致性能下降,这个问题通常发生在表格大于1GB(更是下文提到BillRun系统中的痛点——单表格动辄几GB)的情况下。鉴于MongoDB的弱数据结构模式,添加1个新字段不会对旧表格有任何影响,整个过程会非常快速;因此,在应用程序发生改变时,你不需要专门的1个DBA去修改数据库模式。
2.tcp/ip三次握手;这是送分题,我却忘记了,愚蠢
-
第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
-
第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
-
第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。
完成了三次握手,客户端和服务器端就可以开始传送数据。以上就是TCP三次握手的总体介绍。
当客户端和服务器通过三次握手建立了TCP连接以后,当数据传送完毕,肯定是要断开TCP连接的啊。那对于TCP的断开连接,这里就有了神秘的“四次分手”。
-
第一次分手:主机1(可以使客户端,也可以是服务器端),设置Sequence Number和Acknowledgment Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;
-
第二次分手:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我也没有数据要发送了,可以进行关闭连接了;
-
第三次分手:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入CLOSE_WAIT状态;
-
第四次分手:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。
更多详细tcp/ip的内容不在此记录
3.用户请求从浏览器到服务器的过程(回答的不是很好,讲得不够清晰)
1.首先,浏览器发送http请求
2.若该请求是请求静态资源(html,css等),则web server能自行处理,返回静态资源.
3.若该请求是请求动态资源(jsp等),则Web Server就会交由Application Server处理,处理的结果再传给Web Server返回浏览器.
那么,你可能会问,什么是Web Server?什么是Application Server?简单来说,Web Server是可以向浏览器提供静态资源的程序,当然了,它还能将请求转发给Application Server处理.Application Server能提供动态资源,同时也具备了Web Server处理请求的能力(但没有那么专业).对了,Tomcat就是一种Application Server.顺便一提,企业级开发中,Web Server是和Application Server共同协作,分工明确的,一个提供静态资源,一个提供动态资源,这样能很好地提高处理请求的效率.
额,那么Servlet又是如何工作的呢?其实,Servlet是归Web容器管理的,Web容器管理着Servlet的整个生命周期,向Servlet提供请求和响应,调用Servlet的方法,所以Servlet类无需main方法.而Web容器是在Application Server上的.Web容器可能有点理解,其实你也可以将Tomcat当成一个Web容器.
既然Servlet是归容器管理的,那么容器又是如何处理请求的呢?
1、用户点击网页内容,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得。
2、Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应。
3、Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host。
4、Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有的Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“ ”的Context去处理)。
5、path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet。Context匹配到URL PATTERN为*.jsp的Servlet,对应于JspServlet类。 (此处接上以下的步骤)
1.当浏览器发送请求,容器会根据URL找到该项目,然后从该项目读取我们编写 Servlet 中的 @WebServlet 标注或者 web.xml 配置,找到能处理该请求的 Servlet.
2.若该Servlet是第一次被访问,则创建Servlet对象servlet,调用servlet的init()方法从配置文件中获取自己的初始化参数,否则直接创建HttpServletRequest和HttpServletResponse的对象request和response.
3.容器为该servlet创建一条线程,然后将request和response对象传给这条线程.
4.容器调用servlet的service()方法,根据请求的不同调用doGet()或doPost()方法.(假设请求方法是get)
5.doGet()方法生成动态页面(其实这是JSP做的),并将结果"放入"response方法.
6.线程结束,容器把response转换成一个HTTP响应,把它传给浏览器,然后删除request和response,线程被销毁.
4.Git的常用指令(送分题)
工作区-->暂缓区/缓存区-->本地仓库
初始化仓库 $ git init
查看仓库状态 $ git status
添加文件到暂存区 $ git add git01.txt
提交到本地仓库 $ git commit -m
命令修改提交备注 $ git commit --amend
查看提交日志 $ git log (-p)+文件名(查看特定文件)
查看更改前后的差异 $git diff
工作区的代码想撤销 $git checkout -- git01.txt
add到暂存区的代码想撤销 先执行$git reset HEAD命令,从暂存区撤销,剩下的操作参考’工作区的代码想撤销’一节。
提交到本地仓库的代码想撤销 $git reset --hard <版本号>HEAD^来描述版本,一个^表示前一个版本,两个^^表示前两个版本,以此类推。2.也可以使用数字来代替^,比如说前100个版本可以写作 HEAD~100。
查看分支 $git branch
切换分支 $ git checkout fa
合并分支 我们先切换到master分支上,然后执行$git merge --no-ff fa (fa为分支名)
本地仓库和这个远程仓库进行关联 $ git remote add origin [email protected]:lenve/test.git
推送到master分支 $ git push -u origin master(-u参数可以在推送的同时,将origin 仓库的master 分支设置为本地仓库当前分支的upstream(上游)。添加了这个参数,将来运行git pull命令从远程仓 库获取内容时,本地仓库的这个分支就可以直接从origin 的master 分支获取内容,省去了另外添加参数的麻烦。这个参数也只用在第一次push 时加上,以后直接运行git push命令即可。)
从远程仓库更新 $git pull
5.linux常用指令(送分题)
待下次补充
6.Mysql的数据引擎(InnoDB 和 MyIsam )
数据库主要引擎有: 1. MyIsam , 2. InnoDB, 3. Memory, 4. Blackhole, 5. CSV, 6. Performance_Schema, 7. Archive, 8. Federated , 9 Mrg_Myisam
有关InnoDB 和 MyIsam 引擎的解释比较:
InnoDB:定义:(默认的存储引擎)
InnoDB是一个事务型的存储引擎,有行级锁定和外键约束。
Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别,关于数据库事务与其隔离级别的内容请见数据库事务与其隔离级别这类型的文章。该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MySQL后台的完整数据库系统,MySQL运行时Innodb会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎不支持FULLTEXT类型的索引,而且它没有保存表的行数,当SELECT COUNT(*) FROM TABLE时需要扫描全表。当需要使用数据库事务时,该引擎当然是首选。由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用Innodb引擎会提升效率。但是使用行级锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表。
InnoDB适用范围:
1)经常更新的表,适合处理多重并发的更新请求。
2)支持事务。
3)可以从灾难中恢复(通过bin-log日志等)。
4)外键约束。只有他支持外键。
5)支持自动增加列属性auto_increment。
MyIsam:定义:MyIASM是MySQL默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当INSERT(插入)或UPDATE(更新)数据时即写操作需要锁定整个表,效率便会低一些。
MyIsam 存储引擎独立于操作系统,也就是可以在windows上使用,也可以比较简单的将数据转移到linux操作系统上去。
意味着:引擎在创建表的时候,会创建三个文件,一个是.frm文件用于存储表的定义,一个是.MYD文件用于存储表的数据,另一个是.MYI文件,存储的是索引。操作系统对大文件的操作是比较慢的,这样将表分为三个文件,那么.MYD这个文件单独来存放数据自然可以优化数据库的查询等操作。有索引管理和字段管理。MyISAM还使用一种表格锁定的机制,来优化多个并发的读写操作,其代价是你需要经常运行OPTIMIZE TABLE命令,来恢复被更新机制所浪费的空间。
适用场景:
1)不支持事务的设计,但是并不代表着有事务操作的项目不能用MyIsam存储引擎,可以在service层进行根据自己的业务需求进行相应的控制。
2)不支持外键的表设计。
3)查询速度很快,如果数据库insert和update的操作比较多的话比较适用。
4)整天 对表进行加锁的场景。
5)MyISAM极度强调快速读取操作。
6)MyIASM中存储了表的行数,于是SELECT COUNT(*) FROM TABLE时只需要直接读取已经保存好的值而不需要进行全表扫描。如果表的读操作远远多于写操作且不需要数据库事务的支持,那么MyIASM也是很好的选择。
缺点:就是不能在表损坏后恢复数据。(是不能主动恢复)
7.Mysql的索引
8.链表的种类及单链表查询的复杂度
单链表指的是链表中的元素的指向只能指向链表中的下一个元素或者为空,元素之间不能相互指向。也就是一种线性链表。
双向链表即是这样一个有序的结点序列,每个链表元素既有指向下一个元素的指针,又有指向前一个元素的指针,其中每个结点都有两种指针,即left和right。left指针指向左边结点,right指针指向右边结点。
循环链表指的是在单向链表和双向链表的基础上,将两种链表的最后一个结点指向第一个结点从而实现循环。
单链表和双链表的区别:
它们都无法在常量时间内随机访问数据。
它们都能够在 O(1) 时间内在给定结点之后或列表开头添加一个新结点。
它们都能够在 O(1) 时间内删除第一个结点。
但是删除给定结点(包括最后一个结点)时略有不同。
在单链表中,它无法获取给定结点的前一个结点,因此在删除给定结点之前我们必须花费 O(N) 时间来找出前一结点。
在双链表中,这会更容易,因为我们可以使用“prev”引用字段获取前一个结点。因此我们可以在 O(1) 时间内删除给定结点。
9.排序算法极其复杂度
不在此总结,详见相关书本
10.红黑树
Java集合中的TreeSet和TreeMap底层为红黑树,红黑树的 时间复杂度为: O(lgn)
二叉查找树
1, 左子树上所有的节点的值均小于或等于他的根节点的值
2, 右子数上所有的节点的值均大于或等于他的根节点的值
3, 左右子树也一定分别为二叉排序树
红黑树就是一种平衡的二叉查找树,说他平衡的意思是他不会变成“瘸子”,左腿特别长或者右腿特别长。除了符合二叉查找树的特性之外,还具体下列的特性:
1. 节点是红色或者黑色
2. 根节点是黑色
3. 每个叶子的节点都是黑色的空节点(NULL)
4. 每个红色节点的两个子节点都是黑色的。
5. 从任意节点到其每个叶子的所有路径都包含相同的黑色节点。(更详细的内容请搜索相关博客)
11.有关项目中遇到的问题以及如何去解决的
此处答得也不算好,需要进一步的去组织语言以及梳理叙述逻辑