程序人生——Java泛型和反射的使用建议,最新软件测试高级面试题汇总
先自我先容一下,小编浙江大学毕业,去过华为、字节跳动等大厂,现在阿里P7深知大多数程序员,想要提升技能,往往是自己摸索发展,但自己不成体系的自学效果低效又漫长,而且极易遇到天花板技术停滞不前!
因此网络整理了一份《2024年最新软件测试全套学习资料》,初志也很简单,就是希望可以或许帮助到想自学提升又不知道该从何学起的朋侪。
https://i-blog.csdnimg.cn/blog_migrate/3ce45fec198917440319c571e4a5a1b6.png
https://i-blog.csdnimg.cn/blog_migrate/b69a7595b22b79e79a46d25a4a625e92.png
https://i-blog.csdnimg.cn/blog_migrate/b7d65b513d21067d3a7ac710a80a606b.png
https://i-blog.csdnimg.cn/blog_migrate/44869f1a20a869767ce83095b311ef1e.png
https://i-blog.csdnimg.cn/blog_migrate/30b1438bbc698ed626da947b08fe60d6.png
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部门目录截图出来,全套包罗大厂面经、学习条记、源码讲义、实战项目、大纲门路、讲解视频,而且后续会连续更新
假如你需要这些资料,可以添加V获取:vip1024b (备注软件测试)
https://i-blog.csdnimg.cn/blog_migrate/1e0cd7306def1627c069287a272de9f0.jpeg
正文
泛型和反射
建议93:Java的泛型是类型擦除的
[*]到场泛型优点:加强了参数类型的安全性,减少了类型的转换。Java的泛型在编译期有效,在运行期被删除,也就是说所有的泛型参数类型在编译后都会被清除掉。所以:1、泛型的class对象时是相同的;2、泛型数组初始化时不能声明泛型类型;3、instanceof不答应存在泛型参数
建议94:不能初始化泛型参数和数组
[*]泛型类型在编译期被擦除,在类初始化时将无法得到泛型的详细参数,所以泛型参数和数组无法初始化,但是ArrayList却可以,因为ArrayList初始化是向上转型变成了Object类型;需要泛型数组解决办法:只声明,不再初始化,由构造函数完成初始化操作
建议95:逼迫声明泛型的实际类型
[*]无法从代码中推断出泛型类型的环境下,即可逼迫声明泛型类型;方法:List list2 = ArrayUtils.asList();在输入前界说这是一个Integer类型的参数
建议96:差异的场景使用差异的泛型通配符
[*]Java泛型支持通配符(Wildcard),可以单独使用一个“?”表现任意类,也可以使用extends关键字表现某一个类(接口)的子类型,还可以使用super关键字表现某一个类(接口)的父类型。1、泛型布局只参与“读”操作则限定上界(extends关键字);2、泛型布局只参与“写”操作则限定下界(使用super关键字);3、假如一个泛型布局既用作“读”操作也用作“写”操作则使用确定的泛型类型即可,如List
建议97:警惕泛型是不能协变和逆变的
[*]Java的泛型是不支持协变和逆变的,只是可以或许实现协变和逆变)(协变和逆变是指宽类型和窄类型在某种环境下(如参数、泛型、返回值)更换或交换的特性。简单地说,协变是用一个窄类型更换宽类型,而逆变则是用宽类型覆盖窄类型。子类覆写父类返回值类型比父类型变窄,则是协变;子类覆写父类型的参数类型变宽,则是逆变。数组支持协变,泛型不支持协变
建议98:建议接纳的次序是List,List,List
[*]List是确定的某一个类型,编码者知道它是一个类型,只是在运行期才确定而已;
[*]List可以进行读写操作,List<?>是只读类型,因为编译器不知道List中容纳的是什么类型的元素,无法增加、修改,但是能删除
建议99:严格限定泛型类型接纳多重边界
[*]使用“&”符号连接多个泛型边界,如:
建议100:数组的真实类型必须是泛型类型的子类型
[*]有大概会抛出ClassCastException异常,toArray方法返回后会进行一次类型转换,Object数组转换成了String数组。由于我们无法在运行期得到泛型类型的参数,因此就需要调用者主动传入T参数类型
建议101:注意Class类的特别性
[*]Java处理的根本机制:先把Java源文件编译成后缀为class的字节码文件,然后再通过ClassLoader机制把这些类文件加载到内存中,最后天生实例实行。Java使用一个元类(MetaClass)来描述加载到内存中的类数据,这就是Class类,它是一个描述类的类对象。Class类是“类中类”,具有特别性:1、无构造函数,不能实例化,Class对象是在加载类时由Java虚拟机通过调用类加载器中的defineClass方法主动构建的;2、可以描述根本类型,8个根本类型在JVM中并不是一个对象,一样平常存在于栈内存中,但是Class类仍旧可以描述它们,比方可以使用int.class表现int类型的类对象;3、其对象都是单例模式,一个Class的实例对象描述一个类,而且只描述一个类,反过来也成立,一个类只有一个Class实例对象。Class类是Java的反射入口,只有在得到了一个类的描述对象后才气动态地加载、调用,一样平常得到一个Class对象有三种途径:1、类属性方式,如String.class;2、对象的getClass方法,如new String().getClass();3、forName方法重载,如Class.forName(“java.lang.String”)。得到了Class对象后,就可以通过getAnnotation()得到注解,通过个体Methods()得到方法,通过getConstructors()得到构造函数等
建议102:适时选择getDeclaredXXX和getXXX
[*]getMethod方法得到的是所有public访问级别的方法,包括从父类继承的方法,而getDeclaredMethod得到的是自身类的所有方法,包括公用方法、私有方法等,而且不受限于访问权限。Java之所以如许处理,是因为反射本意只是正常代码逻辑的一种补充,而不是让正常代码逻辑产生翻天覆地的改动,所以public的属性和方法最容易获取,私有属性和方法也可以获取,但要限定本类。假如需要列出所有继承自父类的方法,需要先得到父类,然后调用getDeclaredMethods方法,之后连续递归
建议103:反射访问属性或方法是将Accessible设置为true
[*]通过反射方式实行方法时,必须在invoke之前检查Accessible属性。而Accessible属性并不是我们语法层级理解的访问权限,而是指是否更容易得到,是否进行安全检查。Accessible属性只是用来判断是否需要进行安全检查的,假如不需要则直接实行,这就可以大幅度地提升系统性能。经过测试,在大量的反射环境下,设置Accessible为true可以提升性能20倍以上
建议104:使用forName动态加载类文件
[*]forName只是加载类,并不实行任何代码)(动态加载(Dynamic Loading)是指在程序运行时加载需要的类库文件,一样平常环境下,一个类文件在启动时或首次初始化时会被加载到内存中,而反射则可以在运行时再决定是否要加载一个类,然后在JVM中加载并初始化。动态加载通常是通过Class.forName(String)实现。一个对象的天生必然会经过一下两个步骤:1、加载到内存中天生Class的实例对象;2、通过new关键字天生实例对象;**动态加载的意义:**加载一个类即表现要初始化该类的static变量,特别是static代码块,在这里我们可以做大量的工作,比如注册自己,初始化环境等,这才是我们重点关注的逻辑
建议105:动态加载不适合数组
[*]通过反射操作数组使用Array类,不要接纳通用的反射处理API)(假如forName要加载一个类,那它起首必须是一个类—8个根本类型清除在外,不是详细的类;其次,它必须具有可追索的类路径,否则会报ClassNotFoundException异常。在Java中,数组是一个非常特别的类,虽然是一个类,但没有界说类路径。作为forName参数时会抛出ClassNotFoundException异常,原因是:数组虽然是一个类,在声明时可以界说为String[],但编译器编译后会为差异的数组类型天生差异的类,所以要想动态创建和访问数组,根本的反射是无法实现的
建议106:动态代理可以使代理模式更加灵活
[*]Java的反射框架提供了动态代理(Dynamic Proxy)机制,答应在运行期对目标类天生代理,避免重复开辟。静态代理是通过代理主题角色(Proxy)和详细主题角色(Real Subject)共同实现抽象主题角色(Subject)的逻辑的,只是代理主题角色把相关的实行逻辑委托给了详细主题角色而已。动态代理需要实现InvocationHandler接口,必须要实现invoke方法,该方法完成了对真实方法的调用
建议107:使用反射增加装饰模式的普适性
[*]装饰模式(Decorator Pattern)的界说是“动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比于天生子类更为灵活”。比较通用的装饰模式,只需要界说被装饰的类及装饰类即可,装饰行为由动态代理实现,实现了对装饰类和被装饰类的完全解耦,提供了系统的扩展性
建议108:反射让模板方法模式更强盛
[*]决定使用模板方法模式时,请尝试使用反射方式实现,它会让你的程序更灵活、更强盛)(模板方法模式(Template Method Pattern)的界说是:界说一个操作中的算法骨架,将一些步骤延迟到子类中,使子类不改变一个算法的布局即可重界说该算法的某些特定步骤。简单说,就是父类界说抽象模板作为骨架,其中包括根本方法(是由子类实现的方法,而且在模板方法被调用)和模板方法(实现对根本方法的调度,完成固定的逻辑),它使用了简单的继承和覆写机制。使用反射后,不需要界说任何抽象方法,只需界说一个根本方法鉴别器即可加载复合规则的根本方法
建议109:不需要太多关注反射服从
[*]反射服从低是个真命题,但因为这一点而不使用它就是个假命题)(反射服从相对于正常的代码实行确实低很多(经测试,相差15倍左右),但是它是一个非常有效的运行期工具类
深入认识JVM
JVM内存分配,类加载
Java进阶(1)——JVM的内存分配 & 反射Class类的类对象 & 创建对象的几种方式 & 类加载(何时进入内存JVM)& 注解 & 反射+注解的案例
https://i-blog.csdnimg.cn/blog_migrate/9d86e3e499c9402c0f39ceb60d0babc4.png
创建对象的4种方法总结
Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化
https://i-blog.csdnimg.cn/blog_migrate/7cb8f7f19bfe1e2d7778aa3a1b112761.png
垃圾接纳GC
https://i-blog.csdnimg.cn/blog_migrate/7a6a26a970996afb73168ac7c45be06b.png
Java进阶(垃圾接纳GC)——理论篇:JVM内存模型 & 垃圾接纳定位清除算法 & JVM中的垃圾接纳器
简介:本篇博客先容JVM的内存模型,对比了1.7和1.8的内存模型的厘革;先容了垃圾接纳的语言发展;论述了定位垃圾的方法,引用计数法和可达性分析发以及垃圾清除算法;然后先容了Java中的垃圾接纳器,由串行、到并行再到并发,最后到G1的演变;最后给出了垃圾接纳器的对比和使用指引。
JVM调优,Arthas使用
[*]Java进阶(JVM调优)——阿里云的Arthas的使用 & 安装和使用 & 死锁查找案例,重新加载案例,慢调用分析
[*]Java进阶(JVM调优)——JVM调优参数 & JDK自带工具使用 & 内存溢出和死锁标题案例 & GC垃圾接纳
https://i-blog.csdnimg.cn/blog_migrate/af9ffe6991dd6b43e5873656cab3a11c.png
https://i-blog.csdnimg.cn/blog_migrate/fe07dfd768e7dfbcfef3c96fd4a63c05.png
https://i-blog.csdnimg.cn/blog_migrate/0e888eb85c22c9bd072906aee6bb84c4.png
网上学习资料一大堆,但假如学到的知识不成体系,遇到标题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋侪,可以添加V获取:vip1024b (备注软件测试)
https://i-blog.csdnimg.cn/blog_migrate/94a571aa4f56590be72fddc03f36654c.jpeg
一个人可以走的很快,但一群人才气走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎到场我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习发展!
份系统化的资料的朋侪,可以添加V获取:vip1024b (备注软件测试)**
[外链图片转存中…(img-lMqc7ATY-1713235887760)]
一个人可以走的很快,但一群人才气走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎到场我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习发展!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]