面试知识点总结

类型相关

1. 如下程序语句有什么问题吗?

short s1 = 1; s1 = s1+1; // 语句1short s2 = 1;s2 += 1; // 语句2

对于语句1,在(s1+1)运算时,会将表达式的类型提升为int,所以将 int 赋值为short类型变量s1时会出现类型转换错误,除非加上强制转换。对于注释2来说,+= 是java定义的运算符,故可以正确编译。

2. char 类型变量能不能存储一个中文汉字?
java的char类型变量是用来存储Unicode编码字符的,由两个字节组成。除了某些生僻的汉字未被Unicode编码收录的,其他的都可以表示。

3. switch 语句能否作用在byte类型变量上,能否作用在long类型变量上,能否作用在 String类型变量上?
由于byte的存储范围小于int,可以向int类型进行隐式转换,所以switch可以作用在 byte 类型上;由于long的存储范围大于int类型,不能向int进行隐式转换,只能强制转换;对于String类型变量在 java1.7版本之前不可以,之后可以。

4. “3*0.1 == 0.3” 将会返回什么?
false,因为浮点数不能完全精确的表示出来,一般都会有精度损失。

5. “float f = 3.4;” 是否正确?
不正确,3.4 是double类型的,将double变量赋值给float会造成精度损失。应写成 float f = (float)3.4; 或者 float f = 3.4F;

6. String、StringBuilder 和 StringBuffer 区别
当处理定长字符串时,建议用String;当处理变长字符串时,并且是单线程环境时,建议用StringBuilder;当处理变长字符串时,并且是多线程环境时,建议用StringBuffer。

7. 关键字 transient 作用
用transient关键字标记的成员变量不参与序列化过程。

8. Comparable 和 Comparator 区别
Comparable是排序接口,若一个类实现了Comparable接口,就意味着该类可以通过Collections.sort或Arrays.sort进行自动排序。Comparator是比较接口,可以通过实现Comparator来新建一个比较器,然后通过这个比较器对类进行排序。
Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。

9.final、finally以及finalize作用

  • final:修饰变量,变量的引用(也就是指向的地址)不可变,但是引用的内容可以变(地址中的内容可变)。
  • finally:表示总是执行。当出现以下情况时,不会执行:①在try中调用System.exit(0),强制退出了程序;②在进入try块前,出现了异常。
  • finalize:一个对象只能执行一次,只能在第一次进入被回收的队列,而且对象所属于的类重写了finalize方法才会被执行。第二次进入回收队列的时候,不会再执行其finalize方法,而是直接被二次标记,在下一次GC的时候被GC。

10.内部类
Java内部类
11.解决哈希冲突的主要方法
①开放定址法。当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。沿此序列逐个单元地查找,直到找到给定的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。查找时探查到开放的地址则表明表中无待查的关键字,即查找失败。
②拉链法。将所有关键字为同义词的结点链接在同一个单链表中。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数组T[0…m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。

与开放定址法相比,拉链法有如下几个优点:
①拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;②由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;③开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;④在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。而对开放地址法构造的散列表,删除结点不能简单地将被删结点的空间置为空,否则将截断在它之后填人散列表的同义词结点的查找路径。这是因为各种开放地址法中,空地址单元(即开放地址)都是查找失败的条件。因此在用开放地址法处理冲突的散列表上执行删除操作,只能在被删结点上做删除标记,而不能真正删除结点。

12.元注解有哪些?
@Retention、@Documented、@Target、@Inherited、@Repeatable

13.Exception和Error有哪些区别?
Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。如StackOverFlowError和OutOfMemoryError。对于这类错误,Java编译器不去检查它们。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和预防,遇到这样的错误,建议让程序终止。Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。

14.类加载过程
分为加载、验证、准备、解析和初始化这5个阶段。
①加载:将类的.class文件中的二进制数据读入内存,放在方法区内。然后在堆中创建Class对象,用来封装类在方法区的数据结构。
②验证:确保被加载的类满足Java虚拟机规范,不会造成安全错误。
③准备:负责为类的静态成员分配内存,并设置默认初始值。
④解析:将类的二进制数据中的符号引用替换为直接引用。
⑤初始化:对static修饰的变量或语句块进行初始化。


集合相关

1. ArrayList 是如何扩增容量的?
ArrayList 使用一个起始容量是10 的数组来存储元素,当数组需要增长时,新的总容量为旧容量的1.5倍。

2.介绍 Map 类

  • HashMap
    HashMap 是基于Map接口实现;允许使用null键和null值;它是无序的,和放入的顺序无关系;是线程不安全的;由数组和链表来实现对数据的存储;初始容量为16;填充因子为0.75。
    添加方法的具体操作:①在添加之前先进行容量的判断,如果当前容量达到了阈值,并且需要存储到Entry[]数组中,先进性扩容操作,空充的容量为table长度的2倍;②重新计算hash值,和数组存储的位置;③然后将新添加的Entry实体存放到当前Entry[]位置链表的头部。在1.8之前,新插入的元素都是放在了链表的头部位置,但是这种操作在高并发的环境下容易导致死锁,所以1.8之后,新插入的元素都放在了链表的尾部。
    在1.8版本之后,当链表长度超过阈值8时,将链表转换为红黑树;链表长度低于6,就把红黑树转回链表。红黑树的平均查找长度是log(n),长度为8,查找长度为log(8)=3,链表的平均查找长度为n/2,当长度为8时,平均查找长度为8/2=4,这才有转换成树的必要。

  • CocurrentHashMap
    ConcurrentHashMap 在JDK1.7版本中将哈希表分成许多片段(segments),每一个片段类似于HashMap,Segment继承了ReentrantLock,因此使用了多个锁来控制对hash表的不同部分进行的修改。在JDK1.8中放弃了锁分离技术,采用CAS算法和synchronized实现线程安全;key和value都不允许为null;get方法是无锁的。

  • TreeMap

3.HashMap与Hashtable有何区别?
① Hashtable是不允许键值为null的,HashMap的键值可以为null;
② Hashtable继承了Dictionary类,HashMap继承的是AbstractMap类;
③ HashMap的初始容量为16,Hashtable初始容量为11,两者负载因子默认都是0.75;
④ Hashtable是线程安全的,HashMap不是线程安全的;
⑤ HashMap扩容时是当前容量翻倍即:2capacity,Hashtable扩容时是容量翻倍+1即:2capacity+1,即前者容量为偶数,后者为奇数;

4.fail-fast和fail-safe迭代器的区别?
fail-safe允许在遍历的过程中对容器中的数据进行修改,而fail-fast则不允许。
fail-fast:是java集合中一种错误检测机制。若直接在容器上进行遍历,在遍历的过程中,一旦发现容器中的数据被修改了,将会立刻抛出ConcurrentModificationException异常,进而导致遍历失败。常见使用fail-fast方式遍历的容器有HashMap和ArrayList等。
fail-safe:这种遍历基于容器的一个克隆。因此,对容器内容的修改不影响遍历。常见的的使用fail-safe方式遍历的容器有ConcerrentHashMap和CopyOnWriteArrayList等。

5.内存泄漏的情况有哪些?
内存泄漏定义:一个不再被程序使用的对象或变量还在内存中占有存储空间。
①静态集合类,如HashMap、LinkedList等等。如果这些容器为静态的,那么它们的生命周期与程序一致,则容器中的对象在程序结束之前将不能被释放,从而造成内存泄漏。
②各种连接,如数据库连接、网络连接和IO连接等。在对数据库进行操作的过程中,首先需要建立与数据库的连接,当不再使用时,需要调用close方法来释放与数据库的连接。只有连接被关闭后,垃圾回收器才会回收对应的对象。
③变量不合理的作用域。一般而言,一个变量的定义的作用范围大于其使用范围,很有可能会造成内存泄漏。另一方面,如果没有及时地把对象设置为null,很有可能导致内存泄漏的发生。
④内部类持有外部类,如果一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即使那个外部类实例对象不再被使用,但由于内部类持有外部类的实例对象,这个外部类对象将不会被垃圾回收,这也会造成内存泄露。
⑤改变哈希值,当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,造成内存泄露。


面向对象

1. 类的实例化顺序
当创建类对象时,先初始化静态变量和静态块,然后是非静态变量和非静态代码块,然后是构造器。由于静态成员只会被初始化一次,所以如果静态成员已经被初始化过,将不会被再次初始化。

2.重载和重写区别
重写的方法和被重写的方法必须具有相同方法名称、参数列表和返回类型,并且重写方法不能使用比被重写的方法更严格的访问权限。
重载的方法名要一样,但是参数类型和个数不一样,返回值类型和访问权限可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。
重写只发生在父类与子类之间,而重载可以发生在同一个类中。

3.面向对象的特征有哪些方面
抽象、继承、多态、封装


多线程

1.自旋锁与互斥锁区别
自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁。

2.自旋锁优缺点
缺点:如果某个线程持有锁的时间过长,就会导致其它等待获取锁的线程进入循环等待,消耗CPU。
优点:不会使线程进入阻塞状态,减少了不必要的上下文切换,执行速度快。

3.乐观锁和悲观锁区别
乐观锁适用于写比较少的情况下,即冲突很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行尝试,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。乐观锁一般会使用版本号机制或CAS算法实现。

4.关键字volatite作用
① 保证变量对所有线程是可见的;②禁止指令重排序优化。
volatile能保证数据的可见性,但不能完全保证数据的原子性,synchronized即保证了数据的可见性也保证了原子性

5.可以实现可见性的关键字有哪些?
① volatile;
② synchronized:对一个变量执行unlock操作之前,必须先把此变量同步回主内存中;
③ final:被final修饰的字段在构造器中一旦完成初始化,那在其他线程中就能看见final字段的值了。

6.this引用逃逸
是指对象还没有构造完成,它的this引用就被发布出去了。例如在类的构造器中创建了一个内部类,此时外部类的成员变量还没初始化完成。但是,同时这个内部类被其他线程获取到,并且调用了内部类可以访问到外部类还没来得及初始化的成员变量的方法。

7.ThreadLocal类的作用
ThreadLocal存放的值是线程封闭,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递。

8.解释可重入锁的概念
自己可以再次获取自己的内部锁。比如有1条线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的,如果不可重入锁的话,就会造成死锁。

9.两个线程交替打印0~100的奇偶数

public class Demo {
	private int i = 0;
	public synchronized void generatorOdd() {
		try {
			while((i&1) == 0) wait();
			System.out.println(
				Thread.currentThread().getName()+": " +i++);
				notify();
		} catch(InterruptedException e) {}
	}

	public synchronized void generatorEvent() {
		try {
			while((i&1) == 1) wait();
			System.out.println(
				Thread.currentThread().getName()+": "+i++);
			notify();
		} catch(InterruptedException e) {}
	}

	public static void main(String[] args) {
		Demo demo = new Demo();
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					for(int i=0; i<50; i++) {
						Thread.sleep(500);
						demo.generatorOdd();
					}
				} catch(InterruptedException e) {}
			}
		}, "奇数").start();
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					for(int i=0; i<50; i++) {
						Thread.sleep(500);
						demo.generatorEvent();
					}
				} catch(InterruptedException e) {}
			}
		}, "偶数").start();
	}
}

虚拟机

1.泛型和类型擦除

2.内存区域介绍

  • 虚拟机栈区:线程私有,存放基本类型、对象的引用和方法的返回值,在编译期间完成分配。
  • 堆区(GC 堆):线程共享,存放对象的实例和数组, 是垃圾收集器管理的主要区域。
  • 方法区:线程共享,存储已被虚拟机加载的类信息、常量、静态变量、编译器编译后的代码等数据。这个区域的内存回收目标主要是针对常量池的对象的回收和对类型的卸载。被称为“永久代”。
  • 程序计数器:线程私有,每个线程都有自己独立的程序计数器,用来指示下一条指令的地址。

Web

1.HttpServlet容器响应Web客户请求流程
①Web客户向Servlet容器发出Http请求;②Servlet容器解析Web客户的Http请求;③Servlet容器创建一个HttpRequest对象,在这个对象中封装Http请求信息;④Servlet容器创建一个HttpResponse对象;⑤Servlet容器调用HttpServlet的service方法来选择执行doGet或是doPost,同时把HttpRequest和HttpResponse对象作为service方法的参数传给HttpServlet对象;⑥HttpServlet通过调用HttpRequest的有关方法,来获取HTTP请求信息;⑦HttpServlet调用HttpResponse的有关方法,生成响应数据;⑧Servlet容器把HttpServlet的响应结果传给Web客户。

2.Hibernate中get()和load()的区别
①get()采用立即加载方式,而load()采用延迟加载;②如果数据库中没有对应的记录时,get()方法返回的是null,而load()方法出现异常ObjectNotFoundException


数据库

1.Statement、 PreparedStatement 、CallableStatement 联系和区别
①Statement、PreparedStatement和CallableStatement都是接口;②Statement继承于Wrapper,PreparedStatement继承于Statement,CallableStatement继承于PreparedStatement;③Statement提供了执行语句和获取结果的基本方法,PrepareStatement增添了处理IN参数的方法,CallableStatement增添了处理OUT参数的方法。

2.PreparedStatement优点
①可以写动态参数化的查询;②SQL语句会预编译在数据库系统中;③阻止常见的SQL注入式攻击;

3.数据库中事务隔离的4个级别
在这里插入图片描述
4.请介绍一些你了解的数据库优化方法
1,设计方面,考虑最优字段,尽量设置非空数据,使用数值型数据,字段的宽度设得尽可能小;
2,查询方面,尽量使用子查询完成多个逻辑的SQL操作,多使用JOIN,对于临时表,多使用联合查询来解决,这样能够保证数据库整齐性;
3,使用事务或锁定表,来保证数据库数据完整性;
4,使用索引,索引能够更有效率的查询数据;
5,查询时最好不要使用 * 号进行查询概括,在有索引的字段尽量不要使用函数操作,尽量不要使用like进行模糊查询,因为影响系统性能;

5.什么是存储过程?有哪些优缺点?
是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。
优点: ①重复使用。存储过程可以重复使用,从而可以减少数据库开发人员的工作量;②减少网络流量。存储过程位于服务器上,调用的时候只需要传递存储过程的名称以及参数就可以了,因此降低了网络传输的数据量;③安全性。参数化的存储过程可以防止SQL注入式攻击。
**缺点:**存储过程,往往定制化于特定的数据库上,因为支持的编程语言不同。当切换到其他厂商的数据库系统时,需要重写原有的存储过程。

6.索引是什么?有什么作用以及优缺点?
索引就是加快检索表中数据的方法。数据库的索引类似于书籍的索引。在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库。

7.drop、truncate、delete三者区别?
truncate table与delete都是删除表数据,保留表结构
truncate table 在功能上与不带 WHERE 子句的 delete语句相同:二者均删除表中的全部行。
truncate 比 delete(一行一行的删)速度快,且使用的系统和事务日志资源少。
truncate 操作后的表比Delete操作后的表要快得多。如果有ROLLBACK命令Delete将被撤销,而 truncate 则不会被撤销。
truncate当表被清空后表和表的索引重新设置成初始大小,而delete则不能。
如果删除表结构及其数据,用 drop table 语句。
执行速度,一般来说: drop> truncate > delete。


数据结构

1.B树、B-树、B+树以及B*树区别

  • B树:搜索二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于走右结点;
  • B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点;所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;
  • B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;到叶子结点才算命中;
  • B*树:在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率从1/2提高到2/3;

2.红黑树
根总是黑色的;如果节点是红色的,则它的子节点必须是黑色的(反之不一定成立); 从根到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点。

Spring

1.介绍IoC
传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

2.介绍DI
比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。spring就是通过反射来实现注入的。

3. 介绍AoP
AOP即面向切面编程,是OOP编程的有效补充。使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。
存在以下4种实现方式:
①使用ProxyFactoryBean和对应的接口实现;
②使用XML配置实现;
③使用@AspectJ注解驱动切面实现;
④使用AspectJ注入切面实现。

4.ApplicationContext通常的实现是什么?

  • FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
  • ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
  • WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。

5.bean作用域有哪些,说一下各种使用场景

  • singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例。
  • prototype:原型模式,当每次注入,或者通过Spring容器获取Bean时,Spring都会为它创建一个新的实例。
  • request:在Web应用中,在一次请求中Spring会创建一个实例,但是不同的请求会创建不同的实例。
  • session:在Web应用中,在会话过程中Spring只创建一个实例。

6.常见注解

注解释义
@Cotroller注解在类上,声明这个类是spring mvc里的Controller,并将其声明为一个spring的Bean
@RequestMapping注解在类上和方法上,映射WEB请求(访问路径和参数)
@ResponseBody支持将返回值放入response体内,而不是返回一个页面(返回的是一个组数据)
@RequestBody允许request的参数在request体中,而不是直接连接在地址后面

正则表达式

1.字符"."可以匹配哪些字符?
匹配除"\r\n"之外的任何单个字符。若要匹配包括"\r\n"在内的任意字符,应使用诸如"[\s\S]"之类的模式。

2.字符"?"有哪些作用?
①零次或一次匹配前面的字符或子表达式。②当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。

3.字符"\b"与"\B"匹配功能是什么?

  • ‘\b’: 匹配一个字边界,即字与空格间的位置。例如,“er\b"匹配"never"中的"er”,但不匹配"verb"中的"er"。
  • ‘\B’: 非字边界匹配。“er\B"匹配"verb"中的"er”,但不匹配"never"中的"er"。

4.断言(?=pattern)、(?!pattern)、(?<=pattern)、(?<!pattern)、(?>pattern)以及(?:pattern)的功能

  • 查看字符串中的当前位置是否紧跟着出现了pattern,而pattern不会成为匹配字符串的一部分。‘A(?=B)’ 匹配后面跟有B的A,但不使B成为匹配的一部分。
  • 查看字符串中的当前位置是否没有 紧跟着出现pattern,而pattern不会成为匹配字符串的一部分。‘A(?!B)’ 匹配后面未跟着B的A。
  • 查看字符串中的当前位置是否前面紧挨着出现了pattern,而pattern不会成为匹配字符串的一部分。’(?<=A)B’匹配前面紧挨着A的B,但不使A成为匹配的一部分。
  • 查看字符串中的当前位置的前面是否没有紧挨着出现pattern,而pattern不会成为匹配字符串的一部分。
  • 仅匹配与pattern匹配的剩余字符串的最大前缀。
  • 该语法在功能上就等效于pattern,是为实现兼容性而提供。

计算机网络

1.TCP滑动窗口、流量控制以及拥塞控制机制

  • 滑动窗口:第一个功能是在不可靠链路上可靠地传输帧。第二个功能是用于保持帧的传输顺序。第三个功能是支持流量控制,它是一种接收方能够控制发送方使其降低速度的反馈机制。
  • 拥塞控制:慢开始、拥塞避免、快重传、快恢复。

2.UDP与TCP区别
①TCP面向连接,UDP是无连接的,即发送数据之前不需要建立连接;②TCP提供可靠服务,通过TCP连接传送的数据无差错、不丢失、不重复,且按序到达,UDP尽最大努力交付,不保证可靠交付;③TCP面向字节流,UDP是面向报文的,UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低,适合应用于实时应用,如IP电话,视频会议;④每一条TCP连接只能是点到点的,UDP支持一对一,一对多,多对一和多对多的交互通信;⑤TCP首部开销20字节,UDP首部开销为8字节;⑥TCP的逻辑通信信道是全双工的可靠信道,UDP是不可靠信道。

3.私有IP地址有哪些?

  • A类:10.0.0.0 ~ 10.255.255.255
  • B类:172.16.0.0 ~ 172.31.255.255
  • C类:192.168.0.0 ~ 192.168.255.255

4.介绍PPP协议
①提供差错检测但不提供纠错功能,只保证无差错接收(通过硬件进行CRC校验)。它是不可靠的传输协议,因此也不使用序号和确认机制;②只支持点对点的链路通信,不支持多点线路;③只支持全双工网路;④PPP的两端可以运行不同的网络层协议,但仍然可以使用同一个PPP进行通信;⑤PPP是面向字节的,当信息字段出现和标志字段一致的比特组合时,PPP有两种不同处理方法:如果PPP用在异步线路(默认)时,采用字节填充法;如果PPP用在等同步线路时,协议规定采用硬件来完成比特填充。

5.常用的熟知端口号举例
FTP(FTP在工作时使用两个并行的TCP连接,一个是控制连接(端口号21) 一个是数据连接(端口号20))、SMTP(25)、DNS(53)、HTTP(80)、

6.HTTP会话建立过程
建立tcp连接;发出请求文档;发出响应文档;释放TCP连接

7.TCP长连接与短连接
长连接多用于频繁操作,多次请求的网络应答响应,而且是一对一,点对点的通信。 例如:数据库的连接用长连接,如果使用短连接频繁的应答响应会造成socket报错,同时也会浪费资源。短连接不会那么耗费资源,因为不需要长时间占用TCP连接。因此,像Web网站中的http服务一般都是用的短连接。

8.WebSocket与http的区别
相同点:①都是应用层协议;②都是基于TCP,并且是可靠的协议;
不同点:①websocket是持久连接的协议,而http是非持久连接的协议;②websocket是双向通信协议,模拟socket协议,可以双向发送消息,而http是单向的;③websocket的服务端可以主动向客服端发送信息,而http的服务端只有在客户端发起请求时才能发送数据,无法主动向客户端发送信息。

9.OSI参考模型以及各层的作用
应用层:为应用程序提供服务;表示层:数据格式转化、数据加密;会话层:建立、管理和维护会话;传输层:建立、管理和维护端到端的连接;网络层:IP选址及路由选择;数据链路层:提供介质访问和链路管理。
OSI参考模型在网络层支持无连接和面向连接通信,但在传输层仅支持面向连接的通信;TCP/IP参考模型在网络层仅有无连接的通信,而在传输层支持无连接和面向连接的通信。

10.数据链路层HDLC和传输层TCP中的滑动窗口区别
①数据链路层是以分组为单位,传输层是以字节为单位;②数据链路层窗口大小不变,且发送窗口大小与接收窗口大小没有必然联系,但是传输层窗口大小动态变化,发送窗口一定小于等于接收窗口。

11. SMTP与POP3的区别
SMTP 采用“推”的通信方式,在用户代理向邮件服务器及邮件服务器之间发送邮件时, SMTP 客户主动将邮件“推”送到 SMTP 服务器。而 POP3 采用“拉”的通信方式,当用户读取邮件时,用户代理向邮件服务器发出请求,“拉”取用户邮箱中的邮件。


软件测试

1.软件测试中的覆盖方法有哪些?

  • 语句覆盖:是使得程序中每个语句至少被执行一次;
  • 判定覆盖:是使得程序中的每个分支至少都通过一次;
  • 条件覆盖:是使得判定中的每个条件获得各种可能的结果;
  • 判定/条件覆盖:是使得判定中的每个条件取到各种可能的值,并使每个判定取到各种可能的结果;
  • 条件组合覆盖:是使得每个判定中条件的各种可能组合都至少出现一次;
  • 路径覆盖:程序中所有可能的路径都被覆盖。

六种覆盖方法中,覆盖准则由弱到强依次是语句覆盖、判定覆盖(分支覆盖)、条件覆盖、判定/条件覆盖、条件组合覆盖、路径覆盖。
满足判定/条件覆盖的测试用例一定同时满足判定覆盖和条件覆盖。
满足组合覆盖的测试用例一定满足判定覆盖、条件覆盖和判定/条件覆盖。

2.白盒、黑盒测试

  • 白盒测试用例设计方法:(有代码检查法、静态结构分析法、静态质量度量法)(属于静态测试类)、逻辑覆盖法、基本路径测试法、域测试 、符号测试、路径覆盖和程序变异。
  • 白盒测试法的覆盖标准有:逻辑覆盖、循环覆盖和基本路径测试。
  • 黑盒测试用例设计方法:等价类划分法、边界值分析法、错误推测法、因果图法、判定表驱动法、正交试验设计法、功能图法、场景法。

3.测试用例的八大要素
用例编号、测试项目、测试标题、重要级别、预置条件、测试输入、测试步骤、预期结果

4.软件测试步骤
单元测试、集成测试、系统测试、确认测试(验收测试)
①单元测试对源程序中每一个程序单元进行测试,检查各个模块是否正确实现规定的功能,从而发现模块在编码中或算法中的错误。该阶段涉及编码和详细设计文档。
②集成测试的主要目的是检查软件单位之间的接口是否正确,主要是针对程序内部结构进行测试,特别是对程序之间的接口进行测试。
③系统测试是基于软件需求说明书的黑盒测试,是对已经集成好的软件系统进行彻底的测试,以验证软件系统的正确性和性能等满足其规约所指定的要求,检查软件的行为和输出是否正确。包括压力测试、功能测试、安全测试、性能测试。
④确认测试主要是检查已实现的软件是否满足需求规格说明书中确定了的各种需求。

5.集成测试包含哪些过程?
①构建的确认过程;②补丁的确认过程;③系统集成测试测试组提交过程;④测试用例设计过程;⑤测试代码编写过程;⑥Bug的报告过程;⑦每周/每两周的构建过程;⑧点对点的测试过程;⑨组内培训过程。

6.软件开发阶段对应的测试
编码——单元测试、详细设计——集成测试、概要设计——系统测试、需求分析——验收测试

7.解释测试驱动开发(TTD)
TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码,通过测试来推动整个开发得进行。

8.测试方法可以分成哪几种?
个人复查、抽查和会审、黑盒测试、白盒测试


基本算法

1.快速排序(升序)

class QuickSort {
	private int[] A;
	public void sort(int start, int end) {
		if(start < end) {
			int p = partition(start, end);
			sort(start, p-1);
			sort(p+1, end);
		}
	}
	private int partition(start, end) {
		int x = A[end], i = start-1;
		for(int j=start; j<end; j++) {
			if(A[j] <= x) {
				i++; swap(A[i], A[j]);
			}
		}
		swap(A[i+1], A[end]);
		return i+1;
	}
}

2.查找第K数

  • 快速排序方式
int elem_k(int[] A, int k) { // A[0..n-1]
	int left = 0, right = A.length-1, i, j;
	while(left < right) {
		i = left-1; j = right+1;
		for(int a = A[(i+j)>>1]; i<j; ) {
			for(j--; a<A[j]; j--);
			for(i++; a>A[i]; i++);
			if(i < j) swap(A[i], A[j]);
		}
		if(k > j) {
			left = j+1;
		} else right = j;
	}
	return A[k];
}

3.KMP

String pattern, string;
int[] next = new int[pattern.length()+1];
next[0] = -1;
for(int i=2, k=0; i<=pattern.length(); i++) {
	while(k>0 && pattern.charAt(k)!=pattern.charAt(i-1))
		k = next[k];
	next[i] = ++k;
}
int i=0, j =0;
while(i<pattern.length() && j<string.length()) {
	if(i==-1 || pattern.charAt(i)==string.charAt(j)) {
		i++; j++;
	} else i = next[i];
}

4.最大连续子序列

int maxsum=0, tmp=0, sum=0, x=0, y=0, left=0, right=0;
for(int i=0; i<n; i++) {
	if(sum >= 0) {
		tmp = sum + arr[i]; y = i;
	} else {
		tmp = arr[i]; x = y = i;
	}
	if(maxsum < tmp) {
		maxsum = tmp; left = x+1; right = y+1;
	}
	sum = tmp;
}

5.堆类(大根堆)

// A[1..n]
void shiftUp(int i) {
	while(i>1 && A[i/2]<A[i]) {
		swap(A[i/2], A[i]);
		i /= 2;
	}
}

void shiftDown(int i) {
	while(2*i <= n) {
		k = 2*i;
		if(k+1<=n && A[k]<A[k+1]) k++;
		if(A[i] > A[k]) break;
		swap(A[i], A[k]);
		i = k;
	}
}

void sort() { for(int i=n/2; i>0; i--) shiftDown(i); }

6.单链表翻转

node_t* m=n; n=n->next; m->next=head; head=m;

在这里插入图片描述
在这里插入图片描述


Linux

1.可以用来获取shell脚本参数的是
在这里插入图片描述

2.Shell特殊变量$*与$@的区别
作用都是获取传递给脚本或函数的所有参数。在没有被双引号包围时,两者没有区别,都是将接受到的每个参数都是独立的,用空格分隔。当被双引号包围时,$@与没有被双引号包围时没有变化,每个参数依然是独立的。但是$*被双引号包围时,会将所有参数看作一个整体

3.常用指令
ifconfig命令被用于配置和显示内核中网络接口的网络参数。
uptime命令可以显示的信息显示依次为:现在时间、系统已经运行了多长时间、目前有多少登陆用户、系统在过去的1分钟、5分钟和15分钟内的平均负载。
top命令可以实时动态地查看系统的整体运行情况,是一个综合了多方信息监测系统性能和运行信息的实用工具。可以用于获取本机cpu使用率。
netstat命令用来打印Linux中网络系统的状态信息,可以得知整个Linux系统的网络情况。
export 用于修改环境变量
env 用于创建环境变量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值