8-5 面向性能的代码调优 第一题 以下关于代码调优的说法,不正确/不恰当的是 A 代码行数越少,代码的执行性能倾向于更好 B 每写完一个method的代码,最好对其性能进行优化,确保时空复杂性优化 C 直到软件开发完全结束、所有其他质量指标均已满足期望,再进行代码调优 D 每次进行代码调优前,必须要使用profiling工具进行性能监控和度量 E 每次代码调优之后、修改代码提交Git仓库之前,都需要进行regression testing 答案:AB
第二题 美于Singleton设计模式,鋭法不正确/不恰当的是 A 符合孩模式的ADT,不血具有constructor,以避免client創建多个突例 B 符合垓模式的ADT,其rep中血具有一-个static的field,其炎型是該ADT本身 C 符合孩模式的ADT,竝具各一-个方法getInstance(),在核方法内迸行垓ADT的new操作 D State没汁模式中,毎个State的具体子炎,可遵守Singleton模式迸行突現 答案:AC A选项:每个类都有constructor,只不 过该模式下的constructor是private的, 不能让client调用 C选项:除非用lazy load的策略,否则 getInstance方法中只需直接返回rep中 的单例对象
第三题 使用Flyweight模式实现文本编辑器中对各个"字母’ 1对象的复用,以下说法不正确的是 A “字母的内容(例如a、 b)是内特性,“字母"在编辑器中展示的字体、字号、颜色是"外特性” B 即使"字母"对象的字体/字号/颜色可变化,但"字母” ADT仍应该是immutable的 C “字母” ADT的rep中需包含其内容、颜色、字体、字号等属性 D 只需要26个大写字母和26个小写字母的对象实例,即足够client在编辑器中使用"字母"的功能 E 客户端代码中需要维护某些数据来管理或计算每个"字母"对象在文档中不同位置的字体、字号、颜色等。 答案:C
第四题 关于Prototype模式,说法不正确的是 A 遵循该模式的ADT,要实现Cloneable接口并override0bject的clone( )方法 B Object的clone( )方法,缺省实现的是shallow copy而非deep copy C 若在调用ADT的clone( )时抛出CloneNotSupportedException,则意味着该ADT没有override0bject的clone( ) D 在进行对象构造时,相比于直接使用构造器来说,使用clone()的代价较小、构造时间更短 答案:CD
第五题 关于Object Pool的说法,不正确的是 A 不采用该模式时,如果一个对象实例不再有活性,即会被GC;采用该模式时,将对象实例加入pool,相当于强行保持其活性而不会被GC B 当client需要一个对象实例时,先到pool中获取,使用完之后,再归还回去 C 原本可被GC的对象,现在要留在pool中,导致内存浪费,但节省了频繁的new和GC的时间 D 不能把不同类型的对象实例放在同一个pool中进行管理,需要分别设定不同的pool 答案:D
第六题 关于Singleton、Flyweight、Object Pool设计模式之间的异同,说法不正确的是 A Singleton相当于把每个class做成了pool,其中包含唯一的对象实例,且是static的 B Flyweight相当于只使用一个对象实例来表示一组具有相同内属性但不同外属性的对象 C Flyweight模式维持一个pool,pool中包含一组具有不同内属性的对象实例 D 这三种模式的client使用某个对象实例时,均需要从pool中申请获得实例、用完归还给pool E 目的都是为了降低new对象实例时的时间代价,降低了程序运行时内存消耗 答案: DE
第七题 以下能够减少创建object的数降低GC的代价 A 方法中的临时变量尽可能使用primitive数据类型(e.g. double),减少使用其对象数据类型(e.g.,Double) B 除非迫不得已(ADT安全性要求),不要使用防御式拷贝 C 对频繁使用的对象用object pool进行canonicalization,哪怕是类似于Integer这样的"小”对象 D 尽量使用String a =“foo”的方式来定义常量字符串,避免new String(“foo") E 尽可能使用类的静态工厂方法进行对象创建,避免直接用new F 在为ADT设计rep的时候,除非迫不得已,最好用简单数据类型 答案:ABCDEF
8-4 动态性能分析方法与工具 第一题 以下关于Dynamic ProgramAnalysis的说法,不正确的是 A 根据程序执行的过程与结果,分析代码在时空性能方面所展现出的性质 B 对程序执行的性能没有影响 C 可用来发现程序中的“热点”语句,即哪些语句被频繁执行 D 只需执行次,即可比测试更容易发现程序中的性能弱点和bug E 能够发现程序中各种不同类型的object分别占用了多少内存空间 答案:BD
第二题 关于profiling的三种策略,说法不正确的是 A 采用代码注入的策略,对程序性能的度量最为准确 B 采用Instrumented VM的策略,需针对不同的VM分别使用不同的profiling工具 C 采用Sampling的策略,对程序执行性能的影响最大 D 采用Instrumented VM和Sampling的策略,均不需对程序代码进行修改 E 采用代码注入的策略,不可能对目标代码进行动态注入 答案:ACE
第三题 关于Java提供的若Fprofiling工具,说法不正确的是 A 有工具可以获取Java程序运行时JVM管理的各heap区域的动态占用情况 B 有工具可以得知指定的Java程序所采用的GC策略 C 有工具可以对正在运行的Java程序的JVM内存配置进行参数的动态设置 D 即使不使用这些工具,当Java程序抛出0utOfMemoryError时,JVM也能够自动导出内存溢出时刻的heap dump E 有工具可以获取当前时刻Java程序主线程的call stack的状态 答案:CD
第四题 图片 从该结果看,在第一次GC前后,survivor space的占用比例增加了_ old generation的占用比例增加了_ A 91.03%,1. 98% B -5.99%,1.39% C -94.55%,-97 .02% D 91.03%,0.37% 答案:B
第五题 不能导出某个Java迸程的heap dump文件的是 A jmap B jcmd C jconsole D jstack E jhat F Eclipse Memory Analyzer 答案: DEF
第六题 使用profiling工具来监控你的Lab3程序时,发现heap中出现了大量的PhysicalObject对象实例,占用了大量内存。可能的原因是___ A 你的Lab3将Physicalobject设计A 为mutable,并对其采取了防御式拷贝策略以避免表示泄漏 B 本次运行读入了一个大文件,故B 构造Circularorbi t对象时不得不构造大量Physicalobject对象 C 导出heap的时刻之前较长时间没有进行GC,故大量无活性的Physica lobject仍处于内存中 D 你的Lab3对Physicalobject的生成(new)采用了"静态工厂”模式,导致JVM无法获取各Physicalobject对象的活性而无法及时GC 答案:ABC
第七题 对代码进行dynamic profiling,不需要在__时候进行 A ADT的初始版本完成后(包括完成了Rep、方法、AF、RI、Spec、各方法的代码) B ADT测试完成后(根据spec设计测试用例,用JUnit执行测试用例并获得结果后) C 每次向Git进行一次commit之前 D ADT迭代开发结束,除性能之外的其他外部和内部质量指标的优化均已经达到期望 E 交付用户之前,发现程序运行缓慢,与期望不符 答案:ABC
10-1 Concurrency 第一题 以下是计算机系统中的concurrency现象? A手机上的一个App通过5G网络访问云端数据 B四核CPU,执行多道程序 C使用Observer设计模式的Java程序,其中Subject类和Observer类的执行 D一亿人同时登录12306网站抢购春运火车票 E使用JVM参数-XX: +UseConcMarkSweepGC启动的程序,运行时进行GC F同一个Java程序内的两个线程,共享一个mutable的 答案:ABDEF
第二题 关于process和thread的说法,不正确的是 A多个process之间不共享内存,而多个thread之间可共享内存 BCPU的某个核,在特定时间点只能运行单一process, 但可并行执行多个thread C手机上的App通过5G网络访问云服务器的资源,手机上和服务器上运行的是不同的thread而非不同的process D一个process可以包含多个thread,一个thread只能在一个process里运行 答案:BC
第三题 关于如何创建thread的说法,不正确的是 A从Thread类派生子类A,创建线程时(new A()).start() B类A实现Runnable接口,并实现其run()方法,创建线程时(new Thread(new A())).run() C new Thread(new Runnable(){ public void run() {…};}) .start(); D new Thread(new Runnable(){ public void run() {…};}).run(); 答案:BD
第四题 关于time slicing, interleaving和race condition的说法,正确的是 ATime slicing由OS决定,但程序员可在代码中进行若干有限度的控制 B如果某程序执行结果的正确与否依赖于time slicing,那么意味着程序执行中产生了racecondition C程序interleaving执行的基本单元是Java代码行 D同一个并发程序的多次执行中的time slicing可能完全不同,因此bug很难复现,将此类bug形象的称为Bohrbugs 答案:AB
第五题 关于Java Thread的sleep( )和interrput(),不正确的是__ A若线程的run( )代码中包含Thread.sleep(100),意味着该线程停止执行100ms, CPU交给其他线程/进程使用 B线程t1中包含代码t1. interrupt(),意味着执行完该语句后t1被终止,不会再获得time slicing C线程t1在sleep( )期间可捕获到其他线程发来的中断信号并抛出InterruptedException异常 D线程若捕获了抛出InterruptedException异常,则自动终止执行 答案:BD
第六题 Thread t = new Thread(new Runnable(){ public void run(){ try{ print(“a”); .*. Thread. sleep( 200); }catch(InterruptedException e){ print(“b”); print(“c”);};}); t.start(); t. interrupt(); 某类的main( )代码如上所示,执行后可能的输出结果为 ac abc
第七题 如果希望让线程执行结束之后再执行其他线程,即让其他线程暂停,需要调用t.join(); 用于“检测当前线程是否收到其他线程发来的中断信号”的Thread静态方法是Thread. isinterrupted() 在线程类的run( )方法中有以下代码,如果希望收到中断信号后终止线程执行,则TODO位置的语句应该是return try{ Thread. sleep(1000); } catch(InterruptedException e){ TODO;}