2021-07-23_面经

常见问题

面经

1

  • java程序是怎样运行的?
  • 最长回文子串
  • linux怎么打开一个文件,查看元素
  • 如何测试人脸识别系统
  • 事务
  • 黑盒白盒测试
  • 单元测试具体方法
  • 测试用例的方法:等价类,边界值,判定表,因果图,正交试验,状态迁移,流程分析,场景分析
  • 测试用例包含哪些要素
  • linux
  • 新用户注册怎么测试
  • mysql左连接右连接
  • 如何解决高并发
  • 为什么选测试?
  • 职业前景规划
  • 元素定位的八种方法
  • get和post
  • 怎么做功能性测试
  • http协议
  • TCP和UDP的区别
  • int 和Integer的区别
  • String为什么要用final修饰?

java基础

封装、继承、多态

  • 多态
    多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
  • Java实现多态有三个必要条件:继承、重写、向上转型。
  1. 继承:在多态中必须存在有继承关系的子类和父类。
  2. 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
  3. 向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。

Java中有两种形式可以实现多态,继承和接口:

java垃圾回收机制

异常处理机制

在Java 应用程序中,异常处理机制为:抛出异常,捕捉异常。

  • 抛出异常:当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。运行时系统负责寻找处置异常的代码并执行。
  • 捕获异常:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适 的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适 的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。

接口和抽象类

抽象类:不能被实例化,子类使用extends继承,可以有构造器,抽象方法可以继承一个类,实现多个接口
接口:是完全不同的类型,子类使用implements实现,不能有构造器,没有main方法,可以继承多个接口;

Collection 和Collections 的区别?

Collection:实现List和Set的接口
Collections:操作map和list的工具类

int 和Integer的区别

  • Integer是int 的包装类,Int是java的一种数据结构
  • integer变量必须实例化后才能使用,int变量不需要
  • integer的默认值是null,int的默认值是0
  • integer实际是对象的引用,int是直接存储数据值

List 和ArrayList,ArrayList和HashSet

  • List:

是一个有序的集合,可以包含重复的元素。
List有两个重要的实现类:ArrayList 和 LinkedList

ArrayList,LinkedList,Vector三者异同?

同:都实现了list接口,存有序的,可重复的,
ArrayList:作为list的主要实现类;线程不安全,效率高;底层使用Object[] elementData存储
LinkedList:对于频繁的插入、删除操作,使用此类效率比ArrayList高; 底层使用双向链表存储;
Vector:作为list的古老实现类; 线程安全,效率低;底层使用Object[]存储

ArrayList(源码分析 ):

底层采用数组实现,
当使用不带参数的构造方法生成ArrayList对象时,实际上会在底层生成一个长度为10的Object类型数组
如果增加的元素个数超过了10个,那么ArrayList底层会新生成一个数组,长度为原数组的1.5倍+1,然后将原数组的内容复制到新数组当中,并且后续增加的内容都会放到新数组当中。当新数组无法容纳增加的元素时,重复该过程。
对于ArrayList元素的删除操作,需要将被删除元素的后续元素向前移动,代价比较高。

LinkedList 源码分析

底层用链表存储
LinkedList l=new LinkedList(); 内部声明了Node类型的first和last属性,默认值为null
l.add(123); 将123封装到Node中,创建了Node对象
其中,Node定义了 next,prev ; 体现了双向链表**

Vector

源码分析:

通过Vector()创造构造器时,都创建了长度为10的数组
扩容时都扩大2倍

HashSet,LinkedHashSet,TreeSet 三者异同

HashSet:作为Set接口的主要实现类;线程不安全;可以存null值
------LinkedHashSet:是HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历;效率更高
TreeSet:可以按照添加的对象指定属性进行排序

添加元素的过程:以HashSet为例:
在这里插入图片描述

HashSet

无序性(不是随机的):存的数据并不是按照数组索引的顺序添加,和哈希值有关
不可重复性:保证添加的元素按照equals()判断时,不能返回true,即相同的元素只能添加一个;

TreeSet

添加的数据要求是相同类的对象;
按照从小到大排

HashMap,LinkedHashMap,TreeMap,Hashtable 异同

HashMap:作为map的主要实现类;线程不安全,效率高;存储null的key和value;
------LinkedHashMap:hashMap的子类;保证遍历时可以按照添加的顺序遍历(底层加了指针);效率更高
TreeMap:保证按照太黏的key-value对进行排序;底层使用红黑树;
Hashtable:作为古老实现类;线程安全,效率低;不能存储null的key和value;
------Properties:Hashtable的子类;常用来处理配置文件。key,value都是String 类型

Map中的key:无序的,不可重复的;使用set存储
Map中的value:无序的,可重复的;使用collection存储
一个键值对:key-value构成了一个Entry对象

HashMap 底层原理

底层:

数组+链表(jdk7之前)
数组+链表+红黑树(jdk8)

底层实现原理(jdk7)
在这里插入图片描述
底层实现原理(jdk8)
在这里插入图片描述
在这里插入图片描述

计算机网络

1

OSI参考模型(开放式系统互联):

应用层、表示层、会话层、传输层、网络层、链路层、物理层。

物理层:同轴电缆、接收器、发送器等
数据链路层:网卡、交换机、网桥
网络层:路由器、网关
传输层:TCP协议、UDP协议
会话层:SQL、ASP、 PHP等
表示层:ASCII、JPEG、PNG、MP3等
应用层:telnet、ssh、http、smtp等

TCP和UDP的区别?

  • TCP是面向连接的,发送数据前必须先建立连接; UDP无连接,发送数据前不需要建立连接
  • TCP连接是点对点的,只能是单个发送方和单个接收方之间的连接; UDP是一对一,一对多,多对多通信
  • TCP提供可靠地交付服务,通过 TCP 传送的数据无差错、不丢失、不重复,按序到达; UDP 使用尽最大努力交付,不保证可靠性,主机不需要维持复杂的连接状态。
  • TCP 是面向字节流的,接收方的字节流必须和发送方的字节流完全一样。应用程序必须有能力识别收到的字节流,把它还原成应用层数据;UDP 面向报文,对应用层报文添加首部后就交付 IP 层。
  • TCP 有拥塞控制;UDP 没有拥塞控制

https过程?

  • 客户发送它支持的算法列表以及一个不重数。
  • 服务器从该列表中选择一种对称加密算法(例如 AES),一种公钥加密算法(例如 RSA)和一种报文鉴别码算法,然后把它的选择、证书,一个不重数返回给客户。
  • 客户通过 CA 提供的公钥验证证书,成功后提取服务器的公钥,生成一个前主密钥 PMS 并发送给服务器。
  • 客户和服务器独立地从 PMS 和不重数中计算出仅用于当前会话的主密钥 MS,然后通过 MS 生成密码和报文鉴别码密钥。此后客户和服务器间发送的所有报文均被加密和鉴别。

Http协议

是一个应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。
特点:

  • 支持客户/服务器模式。
  • 简单快速:客户向服务器请求服务时,只需传送请求方法和路径由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
  • 灵活: HTTP允许传输任意类型的数据对象。正在传输的类型由Content- Type加以标记。
  • 无连接:无连接的含义是限制每次连接只处理一个请求。
  • 无状态: HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。

HTTP 和HTTPS

  • HTTP超文本传输协议,由客户程序和服务器程序实现,客户程序和服务器程序通过交换 HTTP 报文进行会话.HTTP 定义了这些报文的结构以及报文交换的方式,当用户请求一个 Web 页面时,浏览器向服务器发出对该页面中所包含对象的 HTTP 请求报文,服务器接收请求并返回包含这些对象的 HTTP 响应报文。
  • HTTP over SSL,在 HTTP 传输上增加了 SSL 安全套接字层,通过机密性、数据完整性、身份鉴别为 HTTP 事务提供安全保证。SSL 会对数据进行加密并把加密数据送往 TCP 套接字,在接收方,SSL 读取 TCP 套接字的数据并解密,把数据交给应用层。 HTTPS 采用混合加密机制,使用非对称加密传输对称密钥保证传输安全,使用对称加密保证通信效率。

TCP 三次握手的过程?为什么要三次握手?

  • 初始:A和B均处于closed状态,B创建传输进程控制块TCB并进入listend状态,监听端口是否收到连接请求
  • A 向 B 发送连接请求报文,SYN=1,ACK=0,SYN 不可以携带数据,但要消耗一个序号,发送后 A 进入 SYN-SENT 同步已发送状态。
  • B 收到 A 的连接请求报文后,进入 SYN-RCVD 同步已接收状态,如果同意建立连接就会发送给 A 一个连接响应报文,SYN=1,ACK=1,ACK 可以携带数据,不携带的话则不消耗序号。
  • A 收到 B 的确认后还要对该确认再进行一次确认,发送后 A 进入established状态,B 接收到该报文后也进入established状态,客户端会稍早于服务器端建立连接。

原因:

  • 从信息对等角度看,AB 分别要确认自己和对方的发送、接收能力均正常。第二次握手后 B 还不能确定自己的发送和 A 的接收能力。
  • A 的超时连接请求可能会在双方释放连接后到达 B,B 会误以为是 A 发送了新的连接请求,然后创建连接,服务器资源被浪费。

TCP 四次挥手的过程?为什么要四次挥手?

  • 当 A 没有要发送的数据时就会向 B 发送终止连接报文,FIN=1,发送后 A 进入 FIN-WAIT-1 状态。
  • B 收到后发给 A 一个确认报文,A 进入 FIN-WAIT-2 状态,B 进入 CLOSE-WAIT 状态,TCP 进于半关闭状态。
  • 当 B 也准备释放连接时就向 A 发送连接终止报文,FIN=1,重发 ACK=1,之后 B 进入 LAST-ACK 状态。
  • A 收到后要再进行一次确认,ACK=1,之后进入 TIME-WAIT 状态,等待 2MSL 后进入 CLOSED 状态。B 收到确认后进入 CLOSED 状态。

原因:

  • TCP 是全双工通信,两个方向的连接需要单独断开。
    等待 2MSL 的原因:
  • MSL 是最大报文段寿命,等待 2MSL 可以保证 A 发送的最后一个确认报文被 B 接收,如果该报文丢失,B 会超时重传之前的 FIN+ACK 报文,保证 B 正常进入 CLOSED 状态。
  • 2MSL 后,本连接中的所有报文就都会从网络中消失,防止已失效请求造成异常。

cookie和session?

  • cookie 只能存储 ASCII 码,而 session 可以存储任何类型的数据。
  • session 存储在服务器,而 cookie 存储在客户浏览器中,容易被恶意查看
  • session 的运行依赖 session id,而 session id 存在 cookie 中,叫做 JSESSIONID。如果浏览器禁用了 cookie ,同时 session 也会失效(可以通过其它方式实现,比如在 url 中传递 session_id)

DNS 域名解析的流程 ?

1、浏览器先检查自身缓存中有没有被解析过的这个域名对应的ip地址,如果有,解析结束。同时域名被缓存的时间也可通过TTL属性来设置。
2、如果浏览器缓存中没有(专业点叫还没命中),浏览器会检查操作系统缓存中有没有对应的已解析过的结果。而操作系统也有一个域名解析的过程。在windows中可通过c盘里一个叫hosts的文件来设置,如果你在这里指定了一个域名对应的ip地址,那浏览器会首先使用这个ip地址。

但是这种操作系统级别的域名解析规程也被很多黑客利用,通过修改你的hosts文件里的内容把特定的域名解析到他指定的ip地址上,造成所谓的域名劫持。所以在windows7中将hosts文件设置成了readonly,防止被恶意篡改。

3.如果至此还没有命中域名,才会真正的请求本地域名服务器(LDNS)来解析这个域名,这台服务器一般在你的城市的某个角落,距离你不会很远,并且这台服务器的性能都很好,一般都会缓存域名解析结果,大约80%的域名解析到这里就完成了。
4. 如果LDNS仍然没有命中,就直接跳到Root Server 域名服务器请求解析
5. 根域名服务器返回给LDNS一个所查询域的主域名服务器(gTLD Server,国际顶尖域名服务器,如.com .cn .org等)地址
6. 此时LDNS再发送请求给上一步返回的gTLD
7. 接受请求的gTLD查找并返回这个域名对应的Name Server的地址,这个Name Server就是网站注册的域名服务器
8. Name Server根据映射关系表找到目标ip,返回给LDNS
9. LDNS缓存这个域名和对应的ip
10. LDNS把解析的结果返回给用户,用户根据TTL值缓存到本地系统缓存中,域名解析过程至此结束

MySql

2

事务

  • 事务是一组原子性的 SQL 语句,当有任何一条语句因崩溃或其他原因无法执行时,所有语句都不会执行。事务内的语句要么全部执行成功,要么全部执行失败。

四大特性:

  • 原子性A:一个事务在逻辑上是必须不可分割的最小单元,
  • 一致性C:整个事务中的所有操作要么全部成功,要么全部失败。
  • 隔离性I:事物A与事物B之间具有隔离
  • 持久性D:最终必须持久化到硬盘文件中,此时即使系统崩溃,修改的数据也不会丢失

隔离级别?

  • 未提交读:事务中的修改即使没有提交,对其他事务也是可见的。事务可以读取其他事务修改完但未提交的数据,这种问题称为脏读。这个级别还存在不可重复读和幻读,很少使用。
  • 读已提交(read committed):对方提交后的事物可以读取,解决了脏读现象,但不可重复读
  • 可重复读(repeatable read ):解决了不可重复读的问题,但读取到的数据是幻想。(MySQL默认的隔离级别)
  • 序列化读/串行化读:解决了所有问题,但效率低

内连接和外连接

  • 内连接:查询左右表同时满足条件的记录,两边都不可为 null。
  • 左外连接:以左表为主表,可以查询左表存在而右表为 null 的记录
  • 右外连接:以右表为主表,可以查询右表存在而左表为 null 的记录。

约束

  • 非空约束(not null):约束的字段不能为空
  • 唯一约束(unique):不能重复
  • 主键约束(primarykey):既不能为空,也不能重复(简称PK)
  • 外键约束(foreign key):…简称FK) 检查约束(check):

数据库范式

  • 第一范式:每列都是不可再分的数据单元。
  • 第二范式:在第一范式的基础上消除部分依赖,非主键列完全依赖于主键列。
  • 第三范式:在第二范式的基础上消除传递依赖,非主键列只依赖于主键列。

存储引擎

是表的一种存储方式
mysql默认使用的存储引擎是InnoDB
默认采用的字符集是UTF-8
mysql支持很多存储引擎

查看当前支持的存储引擎?

show engines \G

常见的?

MyISAM

最常用的,但不是默认的,采用三个文件组织一张表
优点:可可被压缩,节省空间
缺点:不支持事物

InnoDB

优点:支持事物,行级锁,支持级联删除、级联更新,

MEMORY

缺点:不支持事物,数据容易丢失
优点:查询速度快

视图

  • 视图是一个虚拟表,是存储在数据库中的查询 SQL 语句,视图只是一个逻辑,具体结果在引用视图时动态生成。
  • 优点:① 具有安全性,可以进行权限控制,创建只读视图,公开给特定用户。② 可以简化复杂的查询,保存其逻辑。

命令

  • 一个完整的DQL语句书写

select…from…where…group by…having…order by…
顺序:from->where->group by->having->select->order by

char 和vchar

char

定长

vchar

可变长

为什么redis适合缓存?

区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件

Linux

1

常用命令

  • pwd 显示当前路径
  • help 查看内置指令
  • shutdown -h now 立刻关机
  • shutdown -h 1 1分钟后关机
  • shutdown -r now 立刻重启
  • shutdown -r 1 1分钟后重启
  • sync 保存内存中数据到磁盘
  • su - 用户名 切换用户
  • whoami 显示当前用户
  • who am i 显示登录用户
  • useradd 用户名 添加用户
  • userdel 用户名 删除用户
  • id 用户名 查看用户信息
  • 修改权限指令chmod : chmod 777 文件名 r=4 w=2 x=1 用数字修改文件权限
  • history 查看历史命令

操作系统

1

多进程、多线程、操作系统

  • 进程:具有独立功能的程序在一个数据集上的一次动态执行的过程,进程是能拥有资源和独立运行的最小单位,也是程序执行的最小单位
  • 线程:是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。

线程间通信方式?

进程间的通信方式?

1、无名管道通信,数据只能单向流动,只能在具有亲缘的进程间使用

2、高级管道通信,将领一个程序当作一个新的进程在当前程序中启动,则他算是当前进程的子进程

3、有名管道通信,允许无亲缘关系进程间的通信

4、消息队列通信,消息队列是由消息的链表,存放在内核中并由消息队列标识符标识,消息队列克服了信息传递信息少等缺点

5、信号量通信,信号量用于控制多个进程对共享资源的访问

6、信号通信,用于通知接受进程某个事件已经发生

7、共享内存通信,共享内存映射一段能被其他进程所访问的内存,往往与其他通信机制配合使用,来实现进程间的同步和通信

8、套接字通信,他用于不同机器之间的进程通信

单例模式

  • 懒汉式(线程安全)
	public class Singleton
	{
		private static Singleton instance;
		private Singleton()
		{
			public static synchronized Singleton getInstance()
			{
				if(instance == null)
				{
					instance=new Singleton();
				}
				return instance;
			}
		}
	}
	

测试相关

基础相关

软件测试的方法

  • 根据是否关注软件内部结构:

黑盒测试,
白盒测试,
灰盒测试

  • 根据是否执行软件:

动态测试
静态测试
手工测试
自动化测试

软件测试类型

功能测试、性能测试、负载测试、压力测试、容量测试、稳定性测试、安全性测试、兼容性测试、GUI测试、可用性测试、异常测试、文档测试、安装与卸载测试、接口测试

冒烟测试

是对软件基本的功能进行测试,目的是确认软件基本的功能正常,保证软件系统能跑的起来可以进行后续的正式测试工作

回归测试

回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。
(引入自动化回归测试将大幅降低系统测试、维护升级等阶段的成本)。

自动化测试

Web测试

App测试

接口测试

测试用例

要素

用例编号;测试项;测试标题;用例属性;用例重要级别;预置条件;测试输入;操作步骤;预期结果;实际结果。

测试用例设计方法

等价类划分
边界值分析法
错误推测法
场景分析法
因果图法
状态迁移法
正交表分析法

淘宝购物车测试
  • GUI方面
  • 功能:添加购物车,结算,删除,满了? 商品降价的更新?
  • 性能
  • 易用性
  • 兼容性
  • 安全
注册和登录模块的测试用例

一:注册测试:

  1. 需求分析
  2. 测试点:冒烟测试,功能测试

二:登录测试:
用户名,密码,验证码? 安全性? 兼容性?

数据结构与算法

算法

查找

二分查找
	public static int binarySearch(int[] arr,int target)
	{
		int left=0;
		int right=arr.length-1;
		while(left<=right)
		{
			int mid=(left+right)/2;
			if(arr[mid]==target)
			{
				return mid;
			}
			else if(arr[mid]>target)
			{
				right=mid-1;
			}
			else
			{
				left=mid+1;
			}
		}
		return -1;
	}

排序

快排
	public static void quicksort(int[] arr,int start,int end)
	{
		if(start<end)
		{
			int stard=arr[start];
			int low=start;
			int high=end;
			while(low<high)
			{
				while(low<high && stard<=arr[high])
				{
					high--;
				}
				
				arr[low]=arr[high];
				
				while(low<high && arr[low]<=stard)
				{
					low++;
				}
				arr[high]=arr[low];
				
			}
			
			arr[low]=stard;
			quicksort(arr,start,low);
			quicksort(arr,low+1,end);
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值