编程规范理解与应用(JAVA) | 合计 | 总题数 | 正确答题数 | 正确率 |
---|---|---|---|---|
核心类库:掌握集合与泛型、多线程编程、反射相关规范 | 集合与泛型:规范相关; 并发与多线程:规范相关,ArrayList动态数组、Vector | 4 | 4 | 100.0% |
代码风格:掌握命名、注释、代码格式规范 | 命名 | 1 | 1 | 100.0% |
扩展类库**:掌握IO编程、日志、正则表达式、数据库编程、网络编程相关规范** | IO编程:规范相关; 数据库编程:规范相关; 序列化:规范相关 | 4 | 3 | 75.0% |
语法知识:掌握变量、数据类型、表达式、控制语句、方法、面向对象、异常相关规范 | 面向对象:规范相关; 数据类型:规范相关 | 6 | 3 | 50.0% |
编程语言能力(JAVA) | 合计 | 总题数 | 正确答题数 | 正确率 |
---|---|---|---|---|
JVM:理解Class格式与类加载过程,掌握运行时数据区结构与定位方法,理解GC原理与常用GC回收器,了解JIT机制 | 运行时数据区; Class格式; JIT; GC; 类加载 | 10 | 8 | 80.0% |
语法知识:深入理解变量、数据类型、表达式、控制语句、方法、面向对象、异常的语法特性 | 方法; 数据类型; 语法知识:深入理解变量、数据类型、表达式、控制语句、方法、面向对象、异常的语法特性; 异常体系; 控制语句 | 10 | 8 | 80.0% |
性能优化:掌握代码级性能优化方法,理解JVM的性能调优方法 | 集合:性能相关; GC:性能相关; 性能优化:掌握代码级性能优化方法,理解JVM的性能调优方法; 方法:性能相关; 表达式:性能相关; 运行时数据区:性能相关; 控制语句:性能相关; IO编程:性能相关 | 8 | 4 | 50.0% |
核心类库:熟练掌握集合与泛型、多线程编程、反射的实战用法 | 反射; 线程; 集合与泛型 | 6 | 3 | 50.0% |
扩展类库:熟练运用IO编程、正则表达式、安全类库等重要类库,掌握数据库编程、网络编程。 | 正则表达式; IO编程; 数据库编程 | 4 | 1 | 25.0% |
-
类加载的
几个7个阶段:(1)加载(字节码转换为方法区的运行时存储结构)
(2)验证( Class 文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚机自身安全)
(3)准备(为类变量--static修饰--的变量分配内存并设置初始值--方法区)
(4)解析(将常量池的符号引用替换为直接引用)
(5) 初始化(虚拟机执行类构造器的过程;虚拟机会保证一个类的 () 方法在多线程环境下被正确的加锁和同步)
(6)使用(类被创建实例并被使用--实例化是分配在堆中)
(7)卸载(当类不再被使用时,JVM对其进行垃圾回收,并释放其占用的内存空间)
一般(2)到(4)这三个阶段又叫链接阶段。
-
类加载——双亲委派机制(如果一个类加载器收到了类加载请求,先看父类加载器能否加载,一直如此到顶端加载器判断能否加载,如果顶端可以加载,则顶端加载,如果不行,则本类加载器加载)
1) 类加载时,判断两个类是否是同一个类,除了要求它们的名字相同外,还要求加载它们的类加载器实例是同一个,只有两者同时满足的情况下,JVM才认为这两个class是相同的。
2)ClassLoader的loadClass方法加载不存在的类会抛ClassNotFoundException,并不是说返回NULL。
3)自定义类加载器实现继承****ClassLoader后**,重写了findClass方法加载指定路径上的class;
4)BoostrapClassLoader加载核心库类(%JAVA_HOME%/lib目录下的jar包和类或者被-Xbootclasspath参数指定的路径中的所有类)--它是用**原生代码(使用C++)**来实现的,并非继承java.lang.ClassLoader
5)Extension加载器加载%JRE_HOME%/lib/ext下的类和jar包,或者java.ext.dirs系统变量所指定的路径下的jar包,System加载器加载CLASSPATH环境指定路径的类,
6)AppClassLoadrer负载加载当前应用classpath下的所有jar包和类。
-
jinfo,info 查看运行环境参数、查看JVM系统参数、命令行参数---不能看内存
-
值不可变类型: Integer、String,在Java 8中,Integer缓存池的大小默认为-128~127。不可变类型有:Boolean, Byte, Character,Short, Double, Float, Integer, Long, String, BigDecimal
-
反射相关:
-
getType() 方法返回的是对象的运行时类型,即 Class 对象,而 getGenericType() 方法返回的是对象的泛型类型,即 Type 对象。
-
具体来说,getType() 方法返回的是 Class 对象,它代表了对象的实际类型,例如 String、Integer、List 等。而 getGenericType() 方法返回的是 Type 对象,它代表了对象的泛型类型,例如 List、Map<Integer, String> 等。
因此,getType() 方法只能获取对象的实际类型,而无法获取对象的泛型类型信息;而 getGenericType() 方法则可以获取对象的泛型类型信息,包括泛型参数的类型、数量等。
-
-
Java集合类
-
ArrayList——当内部存储空间不够时,扩大50%。默认长度是10。
-
Vector—— 当内部存储空间不够时,扩大1倍。默认长度是10。
-
StringBuffer——默认长度是16
-
StringBuilder——默认长度是16
-
HashSet——默认长度是16
-
HashMap——默认长度为16,允许key和value都为null
-
HashTable——默认长度是11
-
XxxBlockingQueue(array的要手工指定,linked默认是Integer.MAX_VALUE)
**线程安全的集合:**vector、hashtable、StringBuffer、ConcurrentMap(不可存放key和value都为null的对象)
非线程安全的集合: ArrayList、LinkeList(双队列)、HashMap、StringBuilder、LinkedHashSet、LinkedHashMap——保持了插入的顺序-->LRU、PriorityQueue
-
-
重写与重载:
重写(Override):
-
发生在父子类之间,方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常
-
重写的返回类型与被重写的返回类型可以不相同,但必须是父类返回值的派生类
-
声明为final或static的方法不能被重写
重载(Overload)
发生在同一个类中
-
-
在java中关于抽象类的描述正确的是()
A、抽象类必须包含一个抽象方法 ——这个我很容易认为是对的,抽象类可以包含抽象方法,也可以包含非抽象方法
B、抽象类的方法必须是抽象的 ——这个我很容易认为是对的
C、声明抽象类必须带有abstract ——这个我很容易认为是错的
D、抽象类可以被实例化 —— 这个显然错误。抽象方法必须在子类中被实现。抽象类的声明必须带有abstract关键字。主要作用是为了被其他类继承。
interface中的属性的默认修饰权限:public static final,方法属性:public abstract
-
JVM:
以下程序运行结果如何,micro.yam文件不存在。
考察异常类及其继承关系:
/** * 科目二 题目,如代码,程序运行结果如何: * A、文件路径, finish * B、ooo,打印异常堆栈,finish * C、ooo,打印异常堆栈 * D、直接抛出类加载异常 * * @author h00284904 * @since 2021-09-27 */ public class JVM_FileParse_Verify { public static final String A = JVM_FileParse_Verify.class.getClassLoader().getResource("micro.yam").getPath(); public static void main(String[] args) { try { System.out.println(JVM_FileParse_Verify.A); } catch (Throwable e) { System.out.println("ooo"); e.printStackTrace(); } System.out.println("finish"); // Exception in thread "main" java.lang.ExceptionInInitializerError // Caused by: java.lang.NullPointerException // at com.huawei.hqh.JVM_FileParse_Verify.<clinit>(JVM_FileParse_Verify.java:14) } }
因为A就在主类中,且是静态,所在调用main之前就已抛出异常
package com.huawei.hqh; class JVM_FileParser { public static final String A = JVM_FileParser.class.getClassLoader().getResource("micro.yam").getPath(); } /** * 功能描述 * * @author h00284904 * @since 2021-09-28 */ public class JVM_FileParser_Verify2 { public static void main(String[] args) { try { System.out.println(JVM_FileParser.A); } catch (Throwable e) { System.out.println("ooo"); e.printStackTrace(); } System.out.println("finish"); } //ooo // java.lang.ExceptionInInitializerError // at com.huawei.hqh.JVM_FileParser_Verify2.main(JVM_FileParser_Verify2.java:15) // Caused by: java.lang.NullPointerException // at com.huawei.hqh.JVM_FileParser.<clinit>(JVM_FileParser_Verify2.java:4) // ... 1 more //finish }
-
线程:
java 中断线程, 下面哪些情况可能导致中断当前线程的运行? (A、B、D)
A. 抛出一个异常
B. 当前线程调用wait()方法等待竞争资源
C. 当前线程创建一个新线程时
D. 当前线程调用sleep()方法时
-
类文件:
ClassFile {
u4 magic; ——固定为“0xCAFEBABE”,作用是确定该文件为一个可被JVM加载的Class文件。
u2 minor_version; ——Class文件的副版本
u2 major_version; ——Class文件的主版本
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count; field_info fields[fields_count];
u2 methods_count; method_info methods[methods_count];
u2 attributes_count; attribute_info attributes[attributes_count];
}
其中,u1、u2、u4分别代表1、2、4个字节无符号数。
说明: javac -g TestClass.java-g:生成所有的调试信息,包括局部变量名和行号信息。 javap -c TestClass > TCC.txt,
对于javap常用的参数:-c:输出字节码Code-l(小写L):输出Code、LineNumberTable与LocalVariableTable-s:输出方法签名(方法的接收参数列表和返回值)-verbose:包含-c、-l以及输出class文件的编译版本,常量池,Stack, Locals, Args_size对于javap而言,常用的就是-c或-verbose 作者:徐家三少 链接:https://juejin.cn/post/6844903464481325064
-
泛型使用之PECS(Producer Extends Consumer Super)原则:当只想从集合中获取元素,请把这个集合看成生产者,请使用<? extends T>,这就是Producer extends原则,PECS原则中的PE部分。
总结PECS原则如果你只需要从集合中获得类型T , 使用<? extends T>通配符如果你只需要将类型T放到集合中, 使用<? super T>通配符如果你既要获取又要放置元素,则不使用任何通配符。例如ListPECS即 Producer extends Consumer super, 为了便于记忆。(《effective java》第28条)为何要PECS原则?你还记得前面提到泛型是不可变(协变、逆变、不变概念)吗?即List和List之间没有任何继承关系。API的参数想要同时兼容2者,则只能使用PECS原则。这样做提升了API的灵活性。 在java集合API中,大量使用了PECS原则,例如java.util.Collections中的集合复制的方法:
public static <T> void copy(List<? super T> dest, List<? extends T> src) { ... }
集合复制是最典型的用法:复制源集合src,主要获得元素,所以用<? extends T>复制目标集合dest,主要是设置元素,所以用<? super T>**当然,为了提升了灵活性,自然牺牲了部分功能。鱼和熊掌不能兼得。**补充说明这里的错误全部是编译阶段不是运行阶段,编译阶段程序是没有运行。所以不能用运行程序的思维来思考。使用泛型,就是要在编译阶段,就找出类型的错误来。 作者:安静的猫咪先生 链接: https://www.jianshu.com/p/e5b8cd33ec94 -
考察NIO:
要从文件中读出第10个字节—FileInputStream,与FileChannel关系等
readAllLines
哪些不属于NIO的buffer: StringBuffer,CharBuffer,IntBuffer,FloatBuffer
skip(9),
-
Netty的高性能体现在哪?ABCDE
A、非阻塞IO
B、内存零拷贝
C、内存池
D、串行化处理读写
E、高性能序列化协议
解读 Netty的高性能表现:
(1)IO线程模型:同步非阻塞,用最少的资源做更多的事情?何解
(2)内存零拷贝:尽量减少不必要的内存拷贝,实现了更高效率的传输
(3)内存池设计:申请的内存可以重用,主要指直接内存。内部实现是通过一棵二叉查找树来管理内存分配情况。
(4)串行化处理读写:避免使用锁带来的性能开销。即消息的处理尽可能在同一个线程内完成,期间不进行线程切换,这样避免了多线程竞争和同步锁。表面上看,串行化设计似乎CPU利用率不高,并发程度不够。但是,通过调整NIO线程池的线程参数,可以同时启动多个串行化的线程并行运行,这种局部无锁化的串行线程设计相比一队列里多个工作线程模型性能更优。
(5)高性能序列化协议:支持ProtoBuf等高性能序列化协议
(6)高效并发编程的体现:volatile的大量、正确使用; CAS和原子类的广泛使用;线程安全容器的使用;通过读写锁提升并发性能。
-
关于Java8 Stream的描述正确的是: Stream跟迭代器类似,再次遍历需要重新生成。
Stream的特点:
- 无存储,Stream不是一种数据结构,也不保存数据,数据源可以是数组、容器、I/O或Channel等;
- 为函数式编程而生,对Stream的任何修改都不会修改数据源;
- 惰性执行,Stream上的中间操作并不会立即执行,只有等到用户真正需要结果时才会执行;
- 一次消费,Stream只能被消费一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成
-
字符流 和 字节流:
- 字节流的基类InputStream/OutputStream,字符流是Reader/Writer
- 字符流最终都会按照字节流处理
-
Optional——主要用来处理每个程序员都会碰到的空指针异常问题,Java9还补充了or()、IfPresentOrElse()及stream()。属于可选值的封装类,即可以为空,也可以包含对象。
关于java optional参照 https://www.jianshu.com/p/63830b7cb743
-
Java 本地方法的正确定义:"它一般在本地声明,异地用C和C++来实现。它的声明有几点要注意:1)native与访问控制符前后的关系不受限制。2)必须在返回类型之前。3)它一般为非抽象类方法。4)native方法在异地实现,象抽象方法一样,所以没有方法体,以分号结束。如下列5种声明: native public void f(); 正确。 private native void f(); 正确。 protected int native f(); 错误,返回类型位置不对,返回类型必须在native之后。 public abstract native void f(); native必然不是abstract的。 native int f(){} 错误,因为存在方法体{} public static native f(); 正确。static与native方法位置随意。"
-
正则表达式
正则表达式/a+(bab)?(caac)*/,下列选项中该正则表达式的子集是?A
A. /a{2} B. /a+(bab){0,1}(ca)+(ca)/ C. /(bab)(caca)/ D. /a(bab){2}(caac)*/
FutureTask : https://pdai.tech/md/java/thread/java-thread-x-juc-executor-FutureTask.html
-
加解密
推荐使用的对称加密算法有: AES
推荐使用的非对称算法有: RSA 推荐使用的数字签名算法有: DSA ECDSA
-
若程序中要获取当前操作系统登录的用户名,应采用如下哪种方法?()
A、提示用户输入
B、由环境变量获取:System.getEnv('USER')
C、由JVM获取:System.getProperty('user.name')
D、启动程序的时候,由程序输入参数输入
从安全考虑和正确性考虑,A和D不行,我错误的选了B,但查规范,没有这样用的,直接获取“USER”,而且B也与操作系统相关。看来答案应该是C,JVM屏蔽了操作系统细节,且规范文档中倒是其它例子有用到。
http://ilearning.huawei.com/edx/subportal/portal/tseacademy?tab_name=tsea-software-development
-
安全编程规范
| 序号 | 类型 | 提要 |
| ---- | --------------- | ------------------------------------------------------------ |
| 1 | 安全目标 | 机密、完整、可用 |
| 2 | 不可信数据 | 文件、注册表、网络、环境变量、命令行、用户输入、用户态数据、进程间通信、函数参数、全局变量 |
| 3 | 可信数据校验 | 1、标准(文件路径)、归一(NFD编码 或 字符串java.text.Normalizer.normalize()/Normalizer.Form.NFKC) 2、输入正则清理,不推荐断言 3、黑白校验 4、输出脱敏 |
| 4 | SQL注入 | RDBMS:SQL注入(绕过检查、篡改数据、探测数据库结构、控制系统) 1、注入案例 ●没有引号,直接拼接字段的(拼接字段如果强转int可避免注入,但强转会出异常) ●order by 后拼接sql的 ●仅校验数据长度无效 2、措施 1、参数化预编译,重复调用效率高,推荐 (拼接后再预编译也可导致注入) 1.1、myBatis '$key$'替换**可注入**,#key#不可注入 1.2、存储过程也可注入 2、输入黑白校验 (黑、白并非推荐,无特殊要求时可优先考虑白) 3、转码,仅针对引号限制字段 |
| 5 | OS注入 命令注入 | OS注入(Dos攻击、篡改数据,隐藏恶意活动) 1、使用jdk的API、输入校验、转码(推荐,对参数注入无效) 2、使用&拼接命令注入,Runtime.exec()避免shell方式执行,Runtime.loadLibrary(用户输入)可能导致注入 3、ping.exe后的均为参数 4、目录遍历攻击,getCanonicalPath()替代getAbsolutePath() 5、POSIX下可使用exec,建议使用WIN32 API CreateProcess 6、外部输入禁止特殊字符对命令注入无效 |
| 6 | XML | 白名单、安全xml库(如dom4j)、转码 1、XXE(外部实体注入) 1.1、危害: ●获取服务端数据:<!ENTITY xxe SYSTEM "file:///etc/passwd" >]> ●探测内部网络:<!ENTITY xxe SYSTEM "https://192.168.1.1/private" >]> ●引用无限文件DOS <!ENTITY xxe SYSTEM "file:///dev/random" >]> 1.2、措施【entities限定 或 重写 的都是XXE】 ●禁止包含实体 .setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);//DOCTYPE ●禁止使用外部实体和参数实体.setFeature("http://xml.org/sax/features/external-general-entities", false); .setFeature("http://xml.org/sax/features/external-parameter-entities", false); ●覆写解析器解析实体的方法 XMLReader resolveEntity(String publicId, String systemId) ●提取实体内容校验 <!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC 2、XML内部实体扩展攻击:消耗目标程序的服务器内存 2.1、措施 ●禁止包含实体 setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);// XXE通用 ●限制实体解析个数 【数目限定的都是内部,对XXE无效】 dbf.setAttribute(“http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit”,“200”); System.setProperty(“entityExpansionLimit”, “200”); factory.setFeature(“http://javax.xml.XMLConstants/feature/secure-processing”, true); 3、XML注入/xPath注入:未对输入做管控,片段插入,非实体攻击 4、防止注入要从外部数据源头开始校验,拼接完成的xml已无校验意义 |
| 7 | XSLT | 使用不安全的XSLT转换XML: 同上secure-processing |
| 8 | 正则注入 | ReDos攻击、敏感信息泄露,不包含CSRF跨站请求构造(输入校验无法防止) 1、措施 ●输入长度限制 ●减少分组使用量 ●避免动态正则 ●Possessive Match会阻止正则表达式引擎尝试。推荐 ●白名单检查 |
| 9 | zip文件解压 | 1、危害 ●文件解压到目标路径之外 ●解压文件消耗过多的系统资源 2、措施 ●调用sanitzeFileName()函数检查文件名称中是否存在路径遍历类问题 ●边读边统计实际解压文件大小及文件数量(不能使用entry.getSize()进行判断) |
| 10 | 日志注入 | 1、日志伪造风险 ●使用白名单对不可信数据进行校验,禁止输入\r\n等换行符,\r\n替换_等,防止日志伪造 ●对不可信数据的长度进行限制 2、隐私/敏感数据的风险(直接使用log.info(XXX)) ●避免任意记录外部输入等不可信数据 ●只有明确为非敏感的数据才可以记录日志中 ●敏感信息用长度固定的*替代 注意: 1、记录日志时,不要主动抛出异常 |
| 11 | 敏感异常 | java.io.FileNotFoundException 底层文件系统结构、文件名列举 java.sql.SQLException 数据库结构、用户名列举 java.net.BindException 非信任客户端可选择服务器端口时可枚举开放端口 java.util.ConcurrentModificationException 可能提供线程非安全代码的相关信息 javax.naming.InsufficientResourcesException 服务器资源不足(可能辅助DoS攻击) java.util.MissingResourceException 资源列举 java.util.jar.JarException 底层文件系统结构 java.lang.OutOfMemoryError DoS攻击 java.lang.StackOverflowError DoS攻击 java.security.acl.NotOwnerException 所有者枚举 注意: 1、转化为简洁的提示信息,抛出非敏感异常 2、异常不作为业务流程控制 |
| 12 | 序列化 | 1、将包含敏感的字段声明为transient来实现 2、通过自定义writeObject()、writeReplace()、writeExternal()这些方法,不将包含敏感信息的字段写入序列化字节流中。 3、对敏感数据先签名再加密[注意顺序] (同一信任域中可直接传递) 4、禁止type功能包含实体 5、推荐使用Xstream组件 替代 XMLDecoder,XStream.setupDefaultSecurity(xst); 6、Java的反序列化操作,可以绕过对象构造函数的执行,但输入数据不能由外部输入指定 |
| 13 | 线程同步 | 1、使用私有不变对象锁(private lock object idiom),使得攻击者无法获取到锁对象 2、基础数据类型如Boolean.FALSE、10、“LOCK”(或intern())等作为锁对象使用时,这些锁对象可被其他线程或功能重用 private final Integer lock = new Integer(count); private final String lock = new String("LOCK"); 3、防止使用getClass()返回的类对象进行同步,应该使用明确的锁对象。 4、private final Lock lock = new ReentrantLock();不要和synchronized(内置锁)混用 5、防止使用实例锁来同步共享静态变量 private static final Object lock = new Object(); 6、关键字 volatile变量可见 synchronized内置锁 7、自增自减不安全,AtomicInteger安全 |
| 14 | 死锁 | 1、异常时未释放锁 2、请求锁和释放锁顺序不当 3、在阻塞操作中持有锁(如误用proc.waitFor()) 注意: 1、同步方法或使用对象内置锁的同步代码块中,直接抛出异常,不会死锁 |
| 15 | IO | 1、临时文件使用完毕应及时删除,流在finally关闭而非try 2、不要将Buffer对象封装的数据暴露给不可信代码:如wrap()、slice()、duplicate(),应使用asReadOnlyBuffer(); 3、正确处理进程的输出流/错误流 .getErrorStream() .getInputStream() 4、创建文件指定访问权限,避免操作共享目录文件 5、Process.getOutputStream() 输出流可给外部程序提供输入;Process.getInputStream() 输入流可接受外部程序输入 |
| 16 | 平台安全 | 1、声明为private或final的方法,可以防止被子类进行覆写 2、编写自定义类加载器时必须调用超类的getPermission()函数,强改jdk版本提示java.security.AccessContrlException:access denied 3、使用强随机数, java.security.SecureRandom 替代 java.util.Random(适用:随机选取路由) ●SessionID的生成(web应用会话) ●挑战算法中的随机数生成 ●验证码的随机数生成 ●生成重要随机文件的文件名 ●生成密钥相关的随机数生成 4、使用SSLSocket代替Socket,服务器通常都被认证(依赖服务端校验),如果服务器有要求,客户端也可以被认证 5、获取操作系统登录用户名: JVM System.getProperty("user.name") 替代OS环境变量获取 6、自动签名认证机制使用JAR文件中公钥验签,无法保证公钥签名恶意篡改,需要额外的检查 7、不能从配置文件中读取明文密码 8、所有安全敏感的代码可放在一个jar包中 9、jmxremot.port=XXXX不要开启,-Xveriy:none不要禁用JVM的字节码验证 10、安全检查:改权限/密码,删日志; 不需要检查的:记录日志 |
| 17 | 编码 | 1、编码encoder注意防御:XSS、SQL注入 2、硬编码指令可直接作为exec()等入参 3、使用<>比较基础数据值替代=/!=,防止异常时数值为负 4、内部类要么是static的,要么就不要实现接口 |
| 18 | 加密 | 1、不安全的加密算法: 分组加密DES、 哈希算法MD5 2、推荐的对称密码算法 AES, 非对称加密 RSA |
- 开发者测试
| 序号 | 类型 | 提要 |
| ---- | ------------ | ------------------------------------------------------------ |
| 1 | DT基础概念 | 1、UT(功能/函数单元测试,注重黑盒测试,关注的是功能、接口,可以DevOps中CI门禁)、IT(集成测试)、ST(系统/子系统测试) |
| 2 | DT测试设计 | 1、根据需求为达到性价比的测试设计,设计测试用例+;<br /> 2、测试要识别因子、因子值、方法。因子值要归类——等价类划分、边界; <br /> 因子值组合设计测试用例——AC(全排列组合,测试用例个数=各个因子的取值个数相乘) <br /> BC(基础组合,测试用例个数=**各个因子的取值个数相加 - 因子个数 + 1** ) <br /> EC(Each Comosite, 测试用例个数=最多因子值的因子值个数) |
| 3 | 测试基础框架 | ( http://ilearning.huawei.com/edx/next/micro/course-v1:HuaweiX+CNE202007271113018-242+microcourse?blockID=8b4313d932774f83b749e38abaca493f ) <br />Java测试基础框架——Junit,是Xunit中的实例:<br />Maven框架,Junit4.11及以上。一般流程为:(1)数据准备;(2)调用函数(测试);(3)断言 <br />@Test ,函数命名一般为when…then… <br />高级断言——assertThat,统一了API,包括is\not\allof\anyof\… <br />Fixture——BeforeClass->RunWith->Before->TestMethod—>After->AfterClass <br />异常测试——(1)Try/Catch中要有断言;(2)assertThrow (3)@Test ExceptedException (4)@Test Except <br />超时——由于测试用例要满足F.I.R.S.T,其中Fast要求不能一直超时阻塞,@Test(timeout=X milliseconds)——适用于方法; @ Rule public Timeout globalTimeout = Timeout.seconds(3) <br />异常忽略说明——@Ignore(String description) <br />Junit4 参数化查询——{(输入,输出),},@RunWith(Parameterized.class) <br /> Junit 进阶优化——Rules : @Rule, Suite:把目前用例都归档 <br />Java测试框架——Mockito: |