百度--测试开发面试

由于自己基础知识不扎实,这次惨败!

1. 一个Android程序的生命周期是什么样的?

描述:程序的生命周期是在Android系统中进程从启动到终止的所有阶段,也就是Android从启动到停止的全过程。==程序的生命周期是由Android系统进行调度和控制的。

①     程序生命周期

a)       Android进程的优先级。

前台进程==

可见进程 ==》服务进程==

后台进程==》空进程

说明:

㈠前台进程:

Android系统中最重要的进程,是与用户正在进行交互的进程。有以下四种情况。·Activity正在与用户进行交互·进程被Activity调用,而且这个进程正在与用户进行交互·进程服务正在执行声明中的回调函数,如OnCreate()OnStart()OnDestroy()·进程的BroadCastReceiver在执行OnReceive()函数

Android系统在多个前台进程同时运行时,可能会出现资源部足的情况,此时会清除部分前台进程,保证主要的用户界面能够及时响应。

           ㈡可见进程

是指部分程序界面能够被用户看见,却不在前台与用户交互,不影响界面事件的进程。

如果一个进程包含服务,且这个服务正被用户可见的Activity调用,此进程同样被视为可见进程。

Androdi进程一般存在少量的可见进程,只有在特殊情况下,Android系统才会为保证前台进程的资源而清除可见进程。

        ㈢服务进程

            服务进程是指包含已启动服务的进程。·没有用户界面·在后台长期运行

Android系统除非不能保证前台进程和可见进程所必要的资源,否则不强行清

除服务进程。

㈣后台进程

后台进程是指不包括任何已经启动的服务,而其没有任何用户可见的Activity的进程

Android系统中一般存在数量较多的后台进程,在系统资源紧张时,系统将优先清除用户较长时间没有见到的后台进程

        ㈤空进程

            空进程是不包含任何活跃组件的进程

空进程在系统紧张时会被首先清除。但为了提高Android应用程序的启动速

度,Android系统会将空进程保存在系统内存用,在用户重新启动该程序时,空进程会被重新使用。

    除了以上优先级以外,一下两个方面也决定了优先级。·进程的优先级取决于所有组件中优先级最高的部分·进程的优先级会根据其他进程的依赖关系而变化。

②     Android组件

a)  组件式可以调用的基本功能模块,Android应用程序是由组件组成的。

b)  Android系统四个组件:ActivityServiceBroadCastReceiver, ContentProvider

Activity和生命周期

a)  Activity生命周期

Activity生命周期是指Activity从启动到销毁的过程

Activity表现为四种状态。

·活动状态:Activity在用户界面中处于最上层,完全能被用户看到,能够与用户进行交互

·暂停状态:Activity界面上被部分遮挡,该Activity不再处于用户界面的最上层,且不能够与用户进行交互

·停止状态:Activity在界面上完全不能被用户看到,也就是说这个Activity被其他Activity全部遮挡

·非活动状态:不在这三种状态中的Activity则处于非活动状态。

b)      四种状态变换关系

  

c)       Activity

先进先出规则

 

             Android应用程序的生命周期 - antsshadow - antsshadow的博客

 

 d)      事件回调函数Android应用程序的生命周期 - antsshadow - antsshadow的博客                                                            Android应用程序的生命周期 - antsshadow - antsshadow的博客

eActivity状态保存/恢复的事件回调函数   

         Android应用程序的生命周期 - antsshadow - antsshadow的博客

       f)事件回调函数的调用顺序             

           Android应用程序的生命周期 - antsshadow - antsshadow的博客

       g)Activity生命周期图和解释。

 许多生命周期的分析都是纸上谈兵,没有经过实际项目的验证,光看些官方文档时不够的,对其的理解也是也不全面不深刻的。

 

activity是单独的,用于处理用户操作。几乎所有的activity都要和用户打交道,所以activity类创建了一个窗口,开发人员可以通过setContentView(View)接口把UI放到activity创建的窗口上,当 activity指向全屏窗口时,也可以用其他方式实现:作为漂浮窗口(通过windowIsFloating的主题集合),或者嵌入到其他的 activity(使用ActivityGroup)。大部分的Activity子类都需要实现以下两个接口:

 

onCreate(Bundle)接口是初始化activity的地方在这儿通常可以调用setContentView(int)设置在资源文件中定义的UI, 使用findViewById(int) 可以获得UI中定义的窗口.

onPause()接口是使用者准备离开activity的地方,在这儿,任何的修改都应该被提交(通常用于ContentProvider保存数据).

为了能够使用Context.startActivity(),所有的activity类都必须在AndroidManifest.xml文件中定义有相关的“activity”项。

 

activity类是Android 应用生命周期的重要部分。

 

Activity生命周期

 

在系统中的Activity被一个Activity栈所管理。当一个新的Activity启动时,将被放置到栈顶,成为运行中的Activity,前一个Activity保留在栈中,不再放到前台,直到新的Activity退出为止。

 

Activity有四种本质区别的状态:

 

在屏幕的前台(Activity栈顶),叫做活动状态或者运行状态(active or running

如果一个Activity失去焦点,但是依然可见(一个新的非全屏的Activity 或者一个透明的Activity 被放置在栈顶),叫做暂停状态(Paused)。一个暂停状态的Activity依然保持活力(保持所有的状态,成员信息,和窗口管理器保持连接),但是在系统内存极端低下的时候将被杀掉。

如果一个Activity被另外的Activity完全覆盖掉,叫做停止状态(Stopped)。它依然保持所有状态和成员信息,但是它不再可见,所以它的窗口被隐藏,当系统内存需要被用在其他地方的时候,StoppedActivity将被杀掉。

如果一个ActivityPaused或者Stopped状态,系统可以将该Activity从内存中删除,Android系统采用两种方式进行删除,要么要求该Activity结束,要么直接杀掉它的进程。当该Activity再次显示给用户时,它必须重新开始和重置前面的状态。

下面的图显示了Activity的重要状态转换,矩形框表明Activity在状态转换之间的回调接口,开发人员可以重载实现以便执行相关代码,带有颜色的椭圆形表明Activity所处的状态。

 

--------------------------

 

activity 生命周期, lifecycle

 

在上图中,Activity有三个关键的循环:

 

整个的生命周期,从onCreate(Bundle)开始到onDestroy()结束。ActivityonCreate()设置所有的“全局”状态,在onDestory()释放所有的资源。例如:某个Activity有一个在后台运行的线程,用于从网络下载数据,则该Activity可以在onCreate()中创建线程,onDestory()中停止线程。

可见的生命周期,从onStart()开始到onStop()结束。在这段时间,可以看到Activity在屏幕上,尽管有可能不在前台,不能和用户交互。在这两个接口之间,需要保持显示给用户的UI数据和资源等,例如:可以在onStart中注册一个IntentReceiver来监听数据变化导致UI的变动,当不再需要显示时候,可以在onStop()中注销它。onStart()onStop()都可以被多次调用,因为Activity随时可以在可见和隐藏之间转换。

前台的生命周期,从onResume()开始到onPause()结束。在这段时间里,该Activity处于所有 Activity的最前面,和用户进行交互。Activity可以经常性地在resumedpaused状态之间切换,例如:当设备准备休眠时,当一个 Activity处理结果被分发时,当一个新的Intent被分发时。所以在这些接口方法中的代码应该属于非常轻量级的。

Activity的整个生命周期都定义在下面的接口方法中,所有方法都可以被重载。所有的Activity都需要实现 onCreate(Bundle)去初始化设置,大部分Activity需要实现onPause()去提交更改过的数据,当前大部分的Activity也需要实现onFreeze()接口,以便恢复在onCreate(Bundle)里面设置的状态。

 

public class Activity extends ApplicationContext {

 

protected void onCreate(Bundle icicle);

 

protected void onStart();

 

protected void onRestart();

 

protected void onResume();

 

protected void onFreeze(Bundle outIcicle);

 

protected void onPause();

 

protected void onStop();

 

protected void onDestroy();}

2. Java中多态的作用?

一、基本概念

 

      多态性:发送消息给某个对象,让该对象自行决定响应何种行为。

      通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。

 

      java 的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。 

 

      1. 如果a是类A的一个引用,那么,a可以指向类A的一个实例,或者说指向类A的一个子类。

      2. 如果a是接口A的一个引用,那么,a必须指向实现了接口A的一个类的实例。

 

 

二、Java多态性实现机制

 

      SUN目前的JVM实现机制,类实例的引用就是指向一个句柄(handle)的指针,这个句柄是一对指针:

      一个指针指向一张表格,实际上这个表格也有两个指针(一个指针指向一个包含了对象的方法表,另外一个指向类对象,表明该对象所属的类型);

      另一个指针指向一块从java堆中为分配出来内存空间。

 

      The Java Virtual Machine does not require any particular internal structure for objects. In Sun's current implementation of the Java Virtual Machine, a reference to a class instance is a pointer to a handle that is itself a pair of pointers: one to a table containing the methods of the object and a pointer to the Class object that represents the type of the object, and the other to the memory allocated from the Java heap for the object data. jvm规范中关于对象内存布局的说明)

 

 

三、总结

 

      1、通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。

 

         DerivedC c2=new DerivedC();

         BaseClass a1= c2;            //BaseClass 基类,DerivedC是继承自BaseClass的子类

         a1.play();                   //play()BaseClassDerivedC中均有定义,即子类覆写了该方法

 

         分析:

         *  为什么子类的类型的对象实例可以覆给超类引用?

         自动实现向上转型。通过该语句,编译器自动将子类实例向上移动,成为通用类型BaseClass

         *  a.play()将执行子类还是父类定义的方法?

         子类的。在运行时期,将根据a这个对象引用实际的类型来获取对应的方法。所以才有多态性。一个基类的对象引用,被赋予不同的子类对象引用,执行该方法时,将表现出不同的行为。

 

         在a1=c2的时候,仍然是存在两个句柄,a1c2,但是a1c2拥有同一块数据内存块和不同的函数表。

 

      2、不能把父类对象引用赋给子类对象引用变量

 

         BaseClass a2=new BaseClass();

         DerivedC c1=a2;//出错

 

         在java里面,向上转型是自动进行的,但是向下转型却不是,需要我们自己定义强制进行。

         c1=(DerivedC)a2; 进行强制转化,也就是向下转型

 

      3、记住一个很简单又很复杂的规则,一个类型引用只能引用引用类型自身含有的方法和变量。

         你可能说这个规则不对的,因为父类引用指向子类对象的时候,最后执行的是子类的方法的。

         其实这并不矛盾,那是因为采用了后期绑定,动态运行的时候又根据型别去调用了子类的方法。而假若子类的这个方法在父类中并没有定义,则会出错。

         例如,DerivedC类在继承BaseClass中定义的函数外,还增加了几个函数(例如 myFun()

 

         分析:

         当你使用父类引用指向子类的时候,其实jvm已经使用了编译器产生的类型信息调整转换了。

         这里你可以这样理解,相当于把不是父类中含有的函数从虚拟函数表中设置为不可见的。注意有可能虚拟函数表中有些函数地址由于在子类中已经被改写了,所以对象虚拟函数表中虚拟函数项目地址已经被设置为子类中完成的方法体的地址了。

 

 

      4JavaC++多态性的比较

 

      jvm关于多态性支持解决方法是和c++中几乎一样的,

      只是c++中编译器很多是把类型信息和虚拟函数信息都放在一个虚拟函数表中,但是利用某种技术来区别。

 

      Java把类型信息和函数信息分开放。Java中在继承以后,子类会重新设置自己的虚拟函数表,这个虚拟函数表中的项目有由两部分组成。从父类继承的虚拟函数和子类自己的虚拟函数。

      虚拟函数调用是经过虚拟函数表间接调用的,所以才得以实现多态的。

 

      Java的所有函数,除了被声明为final的,都是用后期绑定。

      C++实现多态性,使用关键字virtual,为了引起晚捆绑,使用虚函数。若一个函数在基类被声明为virtual,则所有子类中都是virtual的。对虚函数的重定义成为越位。

 

3. 数据结构层次遍历。

  http://blog.sina.com.cn/s/blog_5207b6c401009fq0.html

4. 输入两个有序数组,合成一个有序数组。

class ArraySort
 2 {
 3     //两个有序数组的合并函数
 4     public static int[] MergeList(int a[],int b[])
 5     {
 6         int result[];  
 7         if(checkSort(a) && checkSort(b))  //检查传入的数组是否是有序的
 8         {
 9             result = new int[a.length+b.length];
10             
11             int i=0,j=0,k=0;   //i:用于标示a数组    j:用来标示b数组  k:用来标示传入的数组
12 
13             while(i<a.length && j<b.length)
14                 if(a[i] <= b[j]) {
15                     result[k++] = a[i++];
16                 }else{
17                     result[k++] = b[j++];
18                 }
19 
20             /* 后面连个while循环是用来保证两个数组比较完之后剩下的一个数组里的元素能顺利传入 */
21             while(i < a.length) 
22                 result[k++] = a[i++];
23             while(j < b.length)
24                 result[k++] = b[j++];
25             
26             return result;
27         }
28         else 
29         {
30             System.out.print("非有序数组,不可排序!");
31             return null;
32         }
33     }
34     
35     //检查数组是否是顺序存储的
36     public static boolean checkSort(int a[])
37     {
38         boolean change = true;  //这个标志位是一种优化程序的方法,可以看看我写的冒泡排序优化就会明白了
39         for(int i=0; i<a.length-1 && change; i++)
40         {
41             for(int j=i+1; j<a.length; j++)
42                 if(a[j-1] > a[j])
43                     return false;
44                 else change = false;
45         }
46         return true;        
47     }
48     
49     // 打印函数
50     public static void print(int b[])
51     {
52          for(int i=0; i<b.length ; i++)
53          {
54              System.out.print(b[i] + (i%10 ==9 ? "\n":"\t"));
55          }
56     }
57     
58     public static void main(String args[])
59     {
60         int a[]={1,2,2,3,5,6,7,7};
61         int b[]={1,2,4,5,8,8,9,10,11,12,12,13,14};
62         int c[]= MergeList(a,b);
63         if(c!=null)
64         print(c);
65         else
66             System.out.println("");
67     }
68 }

5. 实习中学习到什么?

6. 你在实习中最大的收获是什么?

7. 测试的流程?

1.需求:阅读需求,理解需求,与客户、开发、架构多方交流,深入了解需求。--testing team 2.测试计划: 根据需求估算测试所需资源(人力、设备等)、所需时间、功能点划分、如何合理分配安排资源等。---testing leader or testing manager 3.用例设计:根据测试计划、任务分配、功能点划分,设计合理的测试用例。---testing leader, senior tester 4.执行测试:根据测试用例的详细步骤,执行测试用例。--every tester(主要是初级测试人员) 5.执行结果记录和bug记录:对每个case记录测试的结果,有bug的在测试管理工具中编写bug记录。--every tester(主要是初级测试人员) 6.defect tracking:追踪leader分配给你追踪的bug.直到 bug fixed。--every tester 7.测试报告:通过不断测试、追踪,直到被测软件达到测试需求要求,并没有重大bug. 8.用户体验、软件发布等……

8. 在测试中怎么做才能做得更好?


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值