几道很有趣的面试题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/byszy/article/details/50210971

图1图2

2、String、StringBuffer与StringBuilder的区别

java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题。现在总结一下,看看他们的不同与相同。

a.可变与不可变

  String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象是不可变的。

    private final char value[];

  StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,如下就是,可知这两种对象都是可变的。

    char[] value;

b.是否多线程安全

  String中的对象是不可变的,也就可以理解为常量,显然线程安全。

  AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。

  StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。看如下源码:

public synchronized StringBuffer reverse() {
    super.reverse();
    return this;
}

public int indexOf(String str) {
    return indexOf(str, 0);        //存在 public synchronized int indexOf(String str, int fromIndex) 方法
}

  StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。

c.StringBuilder与StringBuffer共同点

  StringBuilder与StringBuffer有公共父类AbstractStringBuilder(抽象类)。

  抽象类与接口的其中一个区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。

  StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(…)。只是StringBuffer会在方法上加synchronized关键字,进行同步。

  最后,如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。

3、就是这个图
生命周期

4、略
5、关键是徒手写代码

    private class MyThread extends Thread{

        @Override
        public void run() {
            //do anything you want
        }
    }

6、关键依然是徒手写代码,注意handler要弱引用
7、考察对java锁机制的了解
8、9、10略
11、12、13 依然是手写代码的考察
14、launchMode在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其他Activity实例公用一个task里。这里简单介绍一下task的概念,task是一个具有栈结构的对象,一个task可以管理多个Activity,启动一个应用,也就创建一个与之对应的task。
Activity一共有以下四种launchMode:

standard 默认的启动模式
singleTop
singleTask
singleInstance
我们可以在AndroidManifest.xml配置的android:launchMode属性为以上四种之一即可。
standard模式的原理如下图所示,不管有没有已存在的实例,都生成新的实例。
standard

singleTop模式的原理如下图所示,跳转时系统会先在栈结构中寻找是否有一个FirstActivity实例正位于栈顶,如果有则不再生成新的,而是直接使用。
singleTop
如果是多个Activity,且不是在栈顶模式如果所示,如果发现有对应的Activity实例正位于栈顶,则重复利用,不再生成新的实例,否则重新生成新的实例。
singleTop

singleTask模式的原理图如下图所示:
singleTask
在图中的下半部分是SecondActivity跳转到FirstActivity后的栈结构变化的结果,我们注意到,SecondActivity消失了,没错,在这个跳转过程中系统发现有存在的FirstActivity实例,于是不再生成新的实例,而是将FirstActivity之上的Activity实例统统出栈,将FirstActivity变为栈顶对象,显示到幕前。也许朋友们有疑问,如果将SecondActivity也设置为singleTask模式,那么SecondActivity实例是不是可以唯一呢?在我们这个示例中是不可能的,因为每次从SecondActivity跳转到FirstActivity时,SecondActivity实例都被迫出栈,下次等FirstActivity跳转到SecondActivity时,找不到存在的SecondActivity实例,于是必须生成新的实例。但是如果我们有ThirdActivity,让SecondActivity和ThirdActivity互相跳转,那么SecondActivity实例就可以保证唯一。
这就是singleTask模式,如果发现有对应的Activity实例,则使此Activity实例之上的其他Activity实例统统出栈,使此Activity实例成为栈顶对象,显示到幕前。

singleInstance我们修改FirstActivity的launchMode=”standard”,SecondActivity的launchMode=”singleInstance”,启动模式如下:
singleInstance
这种启动模式比较特殊,因为它会启用一个新的栈结构,将Acitvity放置于这个新的栈结构中,并保证不再有其他Activity实例进入。
我们看到从FirstActivity跳转到SecondActivity时,重新启用了一个新的栈结构,来放置SecondActivity实例,然后按下后退键,再次回到原始栈结构;图中下半部分显示的在SecondActivity中再次跳转到FirstActivity,这个时候系统会在原始栈结构中生成一个FirstActivity实例,然后回退两次,注意,并没有退出,而是回到了SecondActivity,为什么呢?是因为从SecondActivity跳转到FirstActivity的时候,我们的起点变成了SecondActivity实例所在的栈结构,这样一来,我们需要“回归”到这个栈结构。

15、16、18 又是手写代码,listview重写注意需要复写的方法;sqlite注意增删查改的基本用法;sp读取和写入留意editor。

17、AsyncTask、CursorLoader、IntentService、Alarm的用法。
19、略
20、简单多线程的开发

展开阅读全文

几道面试题

07-21

1、以下代码能否通过编译?如果不能,请改成正确代码,并说明原因。rnrn <%rn int subtract(int num1, int num2) rn return num1-num2;rn rn %>rn rn <% rn int number = 100;rn while (number > 0) rn Response.Write("value: " + number + " ");rn number = subtract(number, 1);rn rn %>rn rn rn未通过编译:CS1519: 类、结构或接口成员声明中的标记“while”无效——为什么是这个rn 错误呢?不清楚了。rn改正:将subtract放在 之间。rn rn2、float f=-123.567F;rn int i=(int)f; i的值现在是_____?rn 答案:-123 (float f=123.567F时,是123)rn3、下面的代码中有什么错误吗?_______rn using System;rn class Arn rn public virtual void F()rn Console.WriteLine("A.F");rn rn rn abstract class B:Arn rn public abstract override void F();rn rn ——编译通过rn4、当类T只声明了私有实例构造函数时,则在T的程序文本外部,_不可以_____(可以 or 不可以)从T派生出新的类,____(可以 or 不可以)直接创建T的任何实例。(答案:均受保护级别限制,不可以)rn5、下面这段代码有错误么?rn switch (i)rn case():rn CaseZero();rn break;rn case 1:rn CaseOne();rn break;rn case 2:rn default:rn CaseTwo();rn break;rn rn——原题目的default那行是:“dufault;”,我想应该是笔误吧,改为default:后无错,当i为2和其他值时,执行CaseTwo()。rn6、在下面的例子里rn using System;rn class Arn rn public A()rn PrintFields();rn rn public virtual void PrintFields()rn rn class B:Arn rn int x=1;rn int y;rn public B()rn y=-1;rn rn public override void PrintFields()rn Console.WriteLine("x=0,y=1",x,y);rn rn当使用new B()创建B的实例时,产生什么输出?rn答案:输出为x=1,y=0(继承的子类在new时,先new父类对象,然后new自身私有成员,当调用b.PrintFields()时,则输出x=1,y=-1)rn7、下面的例子中rn using System;rn class Arn rn public static int X;rn static A()rn X=B.Y+1;rn rn rn class Brn rn public static int Y=A.X+1;rn static B()rn static void Main()rn Console.WriteLine("X=0,Y=1",A.X,B.Y);rn rn rn产生的输出结果是什么? X=1,Y=2rn8、下面这段代码输出什么?为什么?rn int i=5;rn int j=5;rn if (Object.ReferenceEquals(i,j))rn Console.WriteLine("Equal");rn elsern Console.WriteLine("Not Equal");rn答案:Not Equal——进行了装箱操作。 论坛

没有更多推荐了,返回首页