面试知识点总结(Part 1)

5 篇文章 0 订阅
1 篇文章 0 订阅

总结一下自己之前面试的时候准备的和问到的知识点。写的比较浅,还需要自己深入展开

1.自我介绍

专业及研究方向、小论文,项目经验


2.排序算法的原理

常见的排序算法主要是冒泡排序、插入排序、选择排序、快速排序、归并排序、堆排序、希尔排序
稳定性:如果a在b之前,且a=b,排序之后a仍然在b之前。称为稳定。
冒泡排序(稳定)
前后两个相邻的元素对比和调整位置,小上大下,
时间复杂度:最好O(n),当数据已经是正序的时候。最差是反序:O(n2)。平均O(n2)。
选择排序(不稳定)
在未排序的数据中,找到最小的值与第一个数据交换。然后再找到最小的值与第二个交换。
在未排序的数据中,选择最小的值,插入到已排序数据的最后一个位置。
时间复杂度都是O(n^2)。
插入排序(稳定)
类似于打牌摸牌的过程。
对于未排序的数据,在已排序的数据中从后向前扫描,找到相应的位置插入。
时间复杂度:最好是数组按照升序排列O(n),最差降序O(n2),平均O(n2)。
归并排序(稳定)
分治法,将长度为n的序列分成n/2长度的两部分,对两个子序列再进行归并排序,将两个排序好的子序列合并成最终的排序序列。
时间复杂度:最佳正序排列O(n),最差和平均O(nlogn)。
快速排序(不稳定)
分治法,将一个串分为两个子串,从数据中挑选一个元素(第一个或者最后一个)作为基准,重新排列数据,比基准小的放前面大的放后面,然后递归的划分两部分进行处理。
时间复杂度:每次选的基准都刚好平分数组 是最佳O(nlogn),最差每次选到的都是最小或者最大的值O(n^2),平均O(nlogn)。
堆排序(不稳定)
利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
时间复杂度:最佳、最差、平均O(nlogn)。
希尔排序(不稳定)


3.数据结构,Hash、树,B树、二叉树等

哈希表:键值对key、value可以直接进行访问。访问过程迅速有效,数据元素可以被更快的定位。
//TODO


4.继承和多态指的是什么?

继承:类与类之间的父子关系,子类继承父类的属性和方法。(子类可以有自己的属性和方法
parent指代父类,self自身。
用“::”运算符。(::还可以用来作为 类常量 和 静态方法 的调用)不能用双冒号:: 访问静态方法。
开发设计中,需要精心设计专门用于被继承的类;针对不是被继承的类,用final修饰符;子类可进行扩展,而不是覆盖重写父类的方法功能。
多态:同一类的对象收到相同的消息时,会得到不同的结果,结果是不可预测的,多状态的。
在面向对象语言中,接口的多种不同的实现方式即为多态。
多态的意义在于实际开发过程中,只要关心一个接口或者基类的编程,而不必关心一个对象所属的具体类。


5.常见的设计模式有哪些?

工厂模式:在类中定义抽象的方法,在子类中实现,子类继承基类的抽象方法。
例如:定义一个交通工具,里面包含交通工具的方法(启动运行停止等),定义汽车飞机等类实现基类的抽象方法。
单例模式:一个类只能有一个实例,而且自行实例化的,并向整个系统提供该实例。
php项目存在大量的数据库操作,单例模式可以避免大量的new操作消耗资源,随之减少数据库连接次数
观察者模式:定义对象之间一对多的依赖关系,当一个对象的状态发生改变之后,其他所有依赖它的对象都要得到通知并自动刷新。(有点像MVVM架构模式的动态绑定机制)


6.Session和Cookie

Cookie保存在远程的客户端的数据,用来识别和跟踪用户。通过http协议(无状态协议)与服务器进行交互。
PHP中可以用setcookie()方法设置
Cookie保存的位置分两种,文件中和浏览器内存中,和浏览器的策略相关。
Cookie默认的失效时间是直到浏览器关闭,也可以手动设置cookie的过期时间。(可通过js实现)
Session,会话,持续的双向的连接。保持服务器与客户端之间保持会话连接的机制。
客户端请求创建session时,服务器先检查客户端传入的session id,如果有,说明之前已经创建过session,检索使用,检索不到则重新创建。如果客户端没有传入session id,服务器会创建session以及对应session id。
Cookie运行在客户端,由客户端进行管理;Session运行在服务器端,但是sessionID作为Cookie存在客户端

Cookie保存在客户端,而Session则保存服务器端。
Cookie默认保存的最大长度是4K,每个站点保存的cookie个数一般都有限制
从安全性的角度来讲,Session的安全性要高。
从保存内容的类型的角度来讲,Cookie只保存字符串(及能够自动转换成字符串),而Session则可以保存所有的数据类型。
从保存内容的大小的角度来讲,Cookie保存的内容是有限制的,比较小,而Session基本上没有这个限制。
从性能的角度来讲,用Session的话,对服务器的压力会更大一些。

如果浏览器禁用cookie,可以通过URL地址重写来解决。URL地址重写的原理是将该用户的session的ID信息重写到URL地址中,这样即使客户端不支持Cookie,也可以使用session来记录用户状态。


7.GET和POST的区别

GET在浏览器回退时是无害的,而POST会再次提交请求。
GET产生的URL地址可以被Bookmark,而POST不可以。
GET请求会被浏览器主动cache,而POST不会,除非手动设置。
GET请求只能进行url编码,而POST支持多种编码方式。
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
GET请求在URL中传送的参数是有长度限制的,而POST么有。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
GET参数通过URL传递,POST放在Request body中。
GET和POST都是HTTP协议中两种发送请求的方式,基于TCP/IP。本质上就是TCP连接,由于http的规定和浏览器/服务器的限制,导致应用的过程有区别。

!!!GET产生一个TCP数据包,POST产生两个TCP数据包:
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。

1.GET与POST都有自己的语义,不能随便混用。
2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。


8.TCP和UDP

都属于传输层协议。
TCP协议:面向连接的、可靠的、基于字节流
UDP协议:无连接、不可靠、基于报文
TCP,三次握手协议,中包含了专门的传递保证机制,当数据接收方收到发送方传来的信息时,会自动向发送方发出确认消息;发送方只有在接收到该确认消息之后才继续传送其它信息,否则将一直等待直到收到确认信息为止。
UDP协议并不提供数据传送的保证机制。如果在从发送方到接收方的传递过程中出现数据报的丢失,协议本身并不能做出任何检测或提示。因此,通常人们把UDP协议称为不可靠的传输协议。
相对于TCP协议,UDP协议的另外一个不同之处在于如何接收突发性的多个数据报。不同于TCP,UDP并不能确保数据的发送和接收顺序。

三次握手协议 在socket编程中,由客户端发起connect():
①客户端发送TCP的SYN标志位置1的包,以及初始序号x(SYN=1,seq=x),客户端进入SYN_SEND状态;
②服务器发回确认包ACK应答,并将自己的序列放入到seq中,将确认序号设置为客户端发来的序列+1(SYN=1,ACK=1,seq=y,ACKnum=x+1),服务器进入SYN_RCVD状态;
③客户端再次发送确认包ACK,SYN标志位为0,ACK标志位为1,并把服务器发来的ACK序列号+1,放在确认字段中(ACK=1,ACKnum=y+1),客户端进入ESTABLISHED状态。当服务器收到这个包之后,也进入ESTABLISHED状态。
四次挥手协议 在socket编程中,可以由任意一方执行close()操作(以客户端发起为例)
①客户端发送FIN标志位为1的包(FIN=1,seq=x),进入FIN_WAIT_1状态;
②服务器确认客户端的FIN包,发送一个确认ACK包(ACK=1,ACKnum=x+1),表明已收到关闭连接请求,但是不会立即关闭,服务器进入CLOSE_WAIT状态,客户端收到确认包之后,进入FIN_WAIT_2状态,等待服务器关闭;
③服务器准备关闭连接时,向客户端发送断开连接请求,FIN为1(FIN=1,seq=y),服务器进入LAST_ACK状态,等待客户端的最后一次确认;
④客户端收到服务器的关闭连接请求,发送一个确认包(ACK=1,ACKnum=y+1),并进入TIME_WAIT状态,等待可能会出现要求重传的ACK包。服务器收到客户端的ACK之后,关闭连接,进入CLOSE模式。客户端会等待2个最大段生命周期,如果没有收到来自服务器的消息,认为服务器已经关闭,然后关闭自己的连接,进入CLOSE状态。


9.PHP的命名空间和自动加载类?namespace和__autoload

命名空间可以区分相同名的函数。
__autoload根据类名找到文件,然后require,缺点是类名和文件路径关联,修改了文件结构时必须要修改类名。
不同结构层次的文件之间调用,可以用__autoload,当引用了一个不存在的类,__autoload就会被调用,类名会作为参数传递。
PHP5.1以后,提供了spl_autoload_register方法,用来注册__autoload函数,实现自动加载类


10.PHP的GC机制

PHP可以自动进行内存管理,清除不再需要的对象。
PHP使用了引用计数(reference counting)这种单纯的垃圾回收(garbage collection)机制。每个对象都内含一个引用计数器(记录有多少变量指针指向这个内存),每个reference连接到对象,计数器加1。当reference离开生存空间或被设为NULL,计数器减1。当某个对象的引用计数器为零时,PHP知道你将不再需要使用这个对象,释放其所占的内存空间。


11.PHP的超级全局变量

$_SESSION session
$_COOKIE cookie
$_GET 用于收集表单(method=“get”)提交的数据,也可以获取来自url的参数
$_POST 用于收集表单(method=“post”)提交的数据,也可以用来传递变量(发送POST请求)
$_SERVER 服务器变量,获取服务器的信息,服务器的主机名、运行脚本的名称等
$_FILES 文件处理相关


12.PHP的魔术方法有哪些,怎么用?

__construct 和 __destruct
构造函数和析构函数。(构造函数:创建对象,实例化。析构函数:对象被销毁)
__set 和 __get
重载(动态的创建属性和方法)
在给不可访问属性赋值时,__set() 会被调用。读取不可访问属性的值时,__get() 会被调用
__call 和 __callStatic
防止调用不可用的方法而报错
在对象中调用一个不可访问方法时,__call() 会被调用。在静态上下文中调用一个不可访问方法时,__callStatic() 会被调用
__toString
该方法可以声明覆盖对象的行为,当作为一个字符串输出.
可定制输出的结果
__autoLoad
访问的类没有被文件require的时候调用


13.常用的模板引擎介绍

思想来自于MVC模型(将M和V分层),模板引擎是Model和View分层的一种解决方案,便于前后台分工协作。
模板引擎。主要是为了实现逻辑和外在内容的分离,如果不使用模板的话,通常的做法就是php代码和html代码混编。使用了模板之后,则可以将业务逻辑都放到php文件中,而负责显示内容的模板则放到html文件中。
Discuz和Smarty


14.反射API

通过对象可以获取他所属的类、拥有哪些方法。
反射API可以用来文档生成,通过扫描文件里的类,生成描述文档。
通过ReflectionClass,我们可以得到类的以下信息:
1)常量 Contants
2)属性 Property Names
3)方法 Method Names静态
4)属性 Static Properties
5)命名空间 Namespace
6)AClass类是否为final或者abstract


15.熟悉的开发框架有哪些?

ThinkPHP、Yii(接触过)
ThinkPHP基于MVC的轻量级框架。
入口文件配置项目的目录(Application => 其他)
配置文件都采用PHP数组的方式,用C方法获取配置信息
Home模块下,有M、V、C三层目录,(避免Controller层过于臃肿,加一层Service做业务逻辑处理)。Model的命名和数据库表的映射
VoList,把从DB中查到的数据转换成列表对象,在controller层中assign一个变量,在html中通过volist的形式可以直接获取数据。
URL模式,普通模式:http://localhost/?m=home&c=user&a=login&var=value
pathinfo:http://localhost/index.php/home/user/login/var/value/
rewrite:http://localhost/home/user/login/var/value
ThinkPHP3.2版本开始,采用命名空间的形式实现类的自动加载,自动加载类库时,有优先级的问题。先判断是否有类库映射,如果有则自动加载映射定义的文件;判断是否有类的目录,有则以该目录为初始目录
命名空间可以防止项目编码中的类、函数、常量的命名冲突;提高代码可读性。
Yii高性能轻量级的PHP框架


16.分布式结构
//TODO


17.对NoSQL的了解,简述Redis

非关系型数据库,为了解决大规模数据集合多重数据。MangoDB、Redis、Memcached。分布式计算、成本低、结构灵活、半结构化数据、没有复杂的关系。
Redis是key-value类型的内存数据库(新浪微博使用大量的Redis存储数据),提供了Hash表、List(双向链表)
它把整个数据全部加载到内存中,纯内存操作,性能突出,每秒处理10万次读写操作。
Redis支持数据持久化,可以将内存中的数据保存在磁盘中,重启时可以再次加载使用。
Redis支持事务,所有的操作都是原子性的,保证一串原子性命令执行不被中断。


18.如何提高网站性能(分布式、Varnish等等)

减少http请求降低网站的响应时间、减少数据的传输
将多张图片合并成一个文件
合并JS脚本和CSS样式文件
利用浏览器的Cache,避免下载重复的文件(可以使用时间戳的方式强制刷新css、js的缓存)
动态内容静态化
将展示的内容生成html静态页面,减少服务器运行脚本的时间(不能应用在内容经常变化的网站,例如社交网络等)
优化数据库
负载均衡
反向代理服务器(Nginx搭建)等,目的是将流量分散到更多的服务器,降低单台服务器的压力
使用缓存
缓存的方式减少对数据库的访问次数,降低时间


19.对ZendVM的了解

Zend引擎用来解析、翻译和执行PHP脚本
PHP脚本通过Zend引擎编译之后,输出OPCode(操作码),再将OPCode解析执行生成结果


20.MySQL索引的原理

B树:在B树上进行查找包含两部操作(1)在B树中查找结点,(2)在结点中找关键字。操作1是在磁盘上进行的,操作2在内存中。在磁盘上找到指针p所指结点之后,先将结点中的信息读入内存,然后再利用顺序查找或者折半查找查询等于K的关键字。关键字所在结点在B树上的层次数,决定B树查找效率。
正文


21.MySQL索引优化
正文


22.MySQL存储引擎有哪些?他们的特点以及使用场景?

InnoDB、MyISAM
InnoDB支持事务,行级锁;MyISAM非事务型,表级锁
行级锁带来的消耗高于表级锁,但是系统并发访问量较高时,InnoDB性能远高于MyISAM。InnoDB的索引不仅缓存索引本身,也缓存数据,需要耗费更大的内存(然而内存是廉价的)。
InnoDB的使用场景:
读写较少,大量的更新操作
千万条数据的表,并发高
安全性可靠性高
MyISAM使用场景:
读远大于写,更新操作较少
并发不高,不需要事务
表数据量小

23.MySQL如何提升性能(性能优化方案),稳定性提升方案

数据库优化方案:一方面优化SQL,另一方面MySQL配置和优化

SQL优化方案:1.复杂的join查询拆分,否则可能会导致锁定和堵塞;2.like模糊语句优化;列出仅需要查询的字段(不影响速度,但是会节省内存);3.数据量大的时候将limit语句换成between,但是如果数据范围中有断行,会导致between结果少于预期。
MySQL优化:1.选用合适的存储引擎;2.关闭不必要的日志,增加MySQL允许的最大连接数。
MySQL性能提升方案:1.增加硬件配置,CPU和内存;2.数据库分库、分表操作,减少单表体积;3.使用Redis等辅助;4.使用中间件进行分布式部署(Mycat);5.使用数据库连接池(数据库连接的管理和分配,程序可以直接使用现有的数据库连接,不需要重新建立)。

稳定性能提升方案:主从复制,主服务器和从服务器之间切分处理客户端查询的负荷。(负载均衡策略)
增加健壮性,主服务器宕机之后切换到从服务器;从服务器备份,主服务器仍然可以进行操作(更新)

主从同步原理:1.主服务器将用户的更新操作二进制保存到日志文件,由Binlog Dump线程将日志文件传输给从服务器
2.从服务器通过IO线程将主服务器日志文件中的更新操作复制到本地的中继日志文件中
3.从服务器通过另一个SQL线程将中继日志文件中的操作依次在本地执行,从而实现数据同步。
MySQL分表:垂直切分和水平切分。
水平切分:切分到另一个表(按照日期或者取模余数),例如根据日期切分日志表,过于久远的日志直接归档处理。


24.代理和反向代理

介于客户端和服务器之间的另一个服务器称为代理服务器,浏览器发送请求到代理服务器,代理服务器取回所需的资源传回给浏览器。
代理服务器有缓冲功能,类似于大型的Cache,不断的将最新的数据存储到本机的存储器。
从Web服务器来看,代理服务器和用户浏览器的功能是一样的,扮演HTTP代理的角色。
传统代理的对象是客户端,反向代理的对象是服务器程序。
用户通过反向代理服务器直接访问web服务器,反向代理服务器与后端Web服务器的沟通与传统代理本质一样使用HTTP协议。
反向代理的作用:利用反向代理服务器的安全特性处理事务

正向代理:客户端知道服务端,通过代理端连接服务端。代理端所代理的就是服务器
反向代理:服务端知道客户端,客户端并不知道服务端,通过代理端连接服务器。代理端代理的是客户端。


25.进程通信(Interprocess communication,IPC)

管道、消息队列、信号量、共享内存、socket
管道:无名管道,pipe函数在内核中申请开辟一段缓冲区(管道),用于通信,一个写端,一个读端
1.半双工,有固定的写端和读端;2.只能用于有亲缘关系的进程之间通信(父子进程或兄弟进程);3.可以视为特殊的文件,可用read、write等函数对它读写,但是他并不属于任何文件系统,只存在于内存中。

消息队列:消息的链表,存放在内核中。一个消息队列由一个标识符(队列ID)来标识。
1.对象记录的,消息有特定的格式以及特定的优先级;2.消息队列独立于发送与接收进程,进程终止时,消息队列的内容并不会被删除;3.消息队列可以随机查询,不一定要以先进先出的顺序读取,也可以按照消息的类型读取。

信号量:计数器,用来实现进程之前的互斥与同步,而不是存储进程间通信数据。
1.信号量基于操作系统的PV操作,程序对信号量的操作都是原子操作;2.每次对信号量的PV操作不仅限于信号量+1或-1,可以加减任意正整数;3.支持信号量组;4.信号量用于进程间同步,如果需要通信,需要结合共享内存。

共享内存:连个或多个进程共享一个给定的存储区
1.最快的一种IPC,进程直接对内存进行存取;2.多个进程可以同时操作,所以需要进行同步;3.共享内存+信号量经常结合在一起使用,信号量用来同步对共享内存的访问。

socket:利用套接字实现进程间通信,可以实现网络间不同主机的通信,建立的通信是双向的通信。


26.悲观锁和乐观锁

悲观锁:每次拿数据都默认为别人会修改,所以在数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠于数据库提供的锁机制。修改记录之前,会尝试对记录加上“排它锁”,加锁成功之后,对记录进行修改,事务完成之后解锁。
MySQL的InnoDB中使用悲观锁:关闭事务自动提交属性,autocommit=0。更新记录之前可以执行select…for update的方式加排它锁来锁定一条记录,修改完记录之后,在commit提交事务。(行级锁,用到索引)

//0.开始事务
begin;/begin work;/start transaction; (三者选一就可以)
//1.查询出商品信息
select status from t_goods where id=1 for update;
//2.根据商品信息生成订单
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status为2
update t_goods set status=2;
//4.提交事务
commit;//commit work;

悲观锁会的加锁机制,会让数据产生额外的开销,甚至产生死锁;降低了并行性,一个事务锁定一条记录时,其他事务就必须等待

乐观锁:假设认为数据处理不会造成冲突,所以在提交的时候进行检测,如果有冲突,返回报错,交给用户去决策。乐观锁不会用数据库的锁机制,通过记录数据版本、使用时间戳实现。
使用版本号时,在数据初始化的时候指定一个版本号,每次对数据的更新操作都对版本号+1操作,并判断当前本版号是不是该数据的最新版本号。

1.查询出商品信息
select (status,status,version) from t_goods where id=#{id}
2.根据商品信息生成订单
3.修改商品status2
update t_goods 
set status=2,version=version+1
where id=#{id} and version=#{version};

适用于写较少的情况,即冲突很少发生的情况,省去了锁的开销,加大了系统的吞吐量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值