曾经的面试

每一次面试前的准备都是一次对过往知识的回顾和总结...

1.for循环的执行顺序:

猎豹移动的一道Android笔试题,考察的就是for循环的执行顺序

public class ForLoop {
    private static boolean foo(char c) {
        System.out.println(c);
        return true;
    }

    public static void main(String[] args) {
        int i = 0;
        for (foo('A'); foo('B') && i < 2; foo('C')) {
            i++;
            foo('D');
        }
    }
}
输出结果是:ABDCBDCB

for (表达式1; 表达式2; 表达式4) {
      表达式3;
}
for循环的执行顺序:第一次循环,即初始化循环,执行表达式1、表达式2、表达式3(前提表达式2满足)、表达式4;第N>=2次循环,执行表达式2、表达式3(前提表达式2满足)、表达式4。

2.final、finally、finalize的区别:

a.final修饰数据是常量,但必须被初始化(定义时、代码块或构造方法时静态和非静态的区别),默认值不属于初始化;final修饰方法不能被子类重写;final修饰类不能被继承;

b.finally只能用在try/catch语句中,表示发生异常后最终总是被执行,即使return、continue、break也不能影响finally语句块的执行,例如:

private static ReturnException testReturn() {
        try {
            return new ReturnException();
        } catch (Exception e) {
            System.out.println("程序捕获了异常");
        } finally {
            System.out.println("finally类最终会执行");
        }
        return null;
    }

    private static class ReturnException {
        public ReturnException() {
            System.out.println("执行了return语句");
        }
    }

输出:

执行了return语句
finally类最终会执行

编译器在编译return new IOException()时会分为两个步骤,new IOException()在finally之前执行,return在finally之后执行,但catch语句不会被执行;

c.finalize用于垃圾回收器在决定回收对象时,会首先调用它的finallize()方法,在该方法中可以释放系统资源,如关闭输入输出流等;但是在《Java编程思想》这本书中并没有释放系统资源的相关描述,书上说垃圾回收只与内存有关,此方法应该用在“特殊”分配内存的释放上,如JNI为C++分配的内存,实际中输入输出流的关闭也是在try/catch的finally代码块中完成,所以该方法一般不常用。

3.生成长度为100,元素的范围是1~100的随机数组:

这道算法题在实际中的用途是音乐的随机播放,可以用经典的洗牌算法——Fisher–Yates shuffle费雪耶茨洗牌算法:

public static void shuffle(int[] data) {
        int shuffle_key;
        int temp;
        Random rand = new Random();
        int length = data.length;
        for (int i = length - 1; i > 0; i--) {
            shuffle_key = rand.nextInt(i + 1);
            temp = data[i];
            data[i] = data[shuffle_key];
            data[shuffle_key] = temp;
        }
    }
基本思路是从1到i(1<=i<=n)个数字中依次随机抽取一个数字,并放到一个新序列的尾端(该算法通过互换数字实现),逐渐(i--)形成一个新的序列。计算一下概率:如果某个元素被放入第i个位置,就必须是在前i-1次选取中都没有选到它,并且第 i次恰好选中它,其概率是1/n,理论上可以达到等概率随机分布。

4.简述Android IPC(进程间通信)的机制:

Android程序主要是由Activity和Service组成的,这些Activity和Serivice可能运行在同一个进程中,也可能运行在不同的进程中,运行在不同进程的Activity和Service采用了Binder机制实现进程间通信(其实在同一进程中也可以采用Binder机制,不知道为什么,以后再研究)。当在Activity中bindService的时候,Service会返回一个包含了Service业务调用的 Binder对象,通过这个Binder对象,Activity就可以获取Service提供的服务或者数据,这里的服务包括普通服务和基于AIDL的服务。

5.字符串中将连续出现的字符按出现次数从大到小的顺序排序,例如aaabbbbcca则输出bbbb、aaa、cc、a:

基本思路:首先找到连续出现的字符存到List中,然后再排序。

String s = "aaabbbbcccaab";
        List<String> result = new ArrayList<String>();
        for (int i = 0, j = i + 1, l = s.length(); i < l; i = j) {
            char temp = s.charAt(i);
            for (; j < l; j++) {
                if (temp != s.charAt(j)) {
                    result.add(s.substring(i, j));
                    break;
                }
            }
            // 边界
            if (j == l) {
                result.add(s.substring(i, j));
            }
        }
        // 直接插入排序
        int len = result.size();
        for (int i = 1; i < len; i++) {
            for (int j = i; j > 0 && result.get(j - 1).length() < result.get(j).length(); j--) {
                String t = result.get(j);
                result.set(j, result.get(j - 1));
                result.set(j - 1, t);
            }
        }

输出:[bbbb, aaa, ccc, aa, b]

6.对Java中synchronized关键字的理解:

非static的synchronized,无论是synchronized方法还是synchronized代码块,都是对对象上锁(对象锁),多个线程不能同时执行所有synchronized方法或代码块,没有获得锁的线程会阻塞,等待当前线程执行完毕,但可以同时执行其它非synchronized方法;

static的synchronized或synchronized(类.class)是对类上锁(类锁),相当于对代码上锁,多个线程不能同时执行该类的所有static synchronized方法,跟这个类的对象没有关系。

7.sleep 、wait、notify、notifyAll等方法说明:

sleep是Thread类的方法,会使当前线程休眠一段时间后继续执行,Thread.sleep不会导致锁行为的改变,如果当前线程拥有锁,那么Thread.sleep不会让线程释放锁。wait是Object类的方法,在线程中调用对象的wait方法,会使当前线程停止运行,并释放它所拥有的锁,进入等待状态,当在其它线程中调用该对象的notify或notifyAll方法时,如果该线程可以获得锁则继续执行,否则继续等待。

notify只唤醒一个等待当前对象锁的线程,notifyAll唤醒所有等待当前对象锁的线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值