我经历的一些Android面试题及答案
最近在考虑换工作,连续面试了几家公司,这里整理一些比较有意思的面试题(普通面试题和算法题,本人算法基础比较薄,算法题不是强项)。
面试题
java中static静态代码块的调用时机。
java中的静态变量和静态代码块是在类加载的时候就执行的,实例化对象时,先声明并实例化变量再执行构造函数。如果子类继承父类,则先执行父类的静态变量和静态代码块,再执行子类的静态变量和静态代码块。同样,接着在执行父类和子类非静态代码块和构造函数。
注意:(静态)变量和(静态)代码块的也是有执行顺序的,与代码书写的顺序一致。在(静态)代码块中可以使用(静态)变量,但是被使用的(静态)变量必须在(静态)代码块前面声明。
最后给出执行步骤:
1、父类静态变量和静态代码块(先声明的先执行);
2、子类静态变量和静态代码块(先声明的先执行);
3、父类的变量和代码块(先声明的先执行);
4、父类的构造函数;
5、子类的变量和代码块(先声明的先执行);
6、子类的构造函数。
android结构升级容易遇到哪些问题,如何解决?
android 数据库升级完整解决方案
android运行时权限。
android6.0权限机制(一):介绍
android6.0权限机制(一):封装
android6.0权限机制(三):6.0以前国产手机权限处理
android进程保活手段。
实现传言中的黑科技-1像素保活
ams、wms它们之间的关系以及协作状态。
android服务-ams和wms
android内存问题,造成内存泄漏的原因,如何避免内存泄漏。
内存泄漏与排查流程——安卓性能优化
threadlocal是什么,有什么作用。
android的消息机制之threadlocal的工作原理
算法题
简述几种排序算法和它们的时间复杂度。
我回答了冒泡、快速、选择和堆排,这里索性把几种排序的java实现也写一下,查漏补缺。
冒泡排序
/** * 冒泡排序 * @param array 目标数组 */ public static void bubblesort(int []array) { for(int i =0;iarray[j+1]) { int temp = array[j]; array[j]=array[j+1]; array[j+1]=temp; } } } }
快速排序
/** * 快速排序 * @param array 目标数组 * @param low 快排起始坐标 * @param high 快排终止坐标 */ private static void quicksort(int[] array,int low,int high) { if(low > high) { return; } //进行第一次快排,将目标区间一分为2 int i = low; int j = high; int key = array[low]; while(i < j) { //从右往左找到第一个比目标值小的数值位置,标记为j while(i < j && array[j] >= key) { j--; } //从左往右找到第一个比目标数值大的数值位置,标记为i while(i < j && array[i] <= key) { i++; } //互换位置 if(i < j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } } //调整目标基准值的位置 array[low] = array[i]; array[i] = key; quicksort(array,low,i-1); quicksort(array,i+1,high); }
选择排序
/** * 选择排序 * @param array 目标数组 */ public static void selectsort(int[] array) { for(int i = 0;i < array.length;i++) { int min = array[i];//假定起始位置的数值为最小数值 int pivotposition = i;//记录起始位置坐标 for(int j = i;j < array.length;j++) { //找出剩余数组中最小的值,记录其坐标 if(array[j] < min) { pivotposition = j; min = array[pivotposition]; } } //将最小值放入起始位置 if(i != pivotposition) { array[pivotposition] = array[i]; array[i] = min; } } }
插入排序
/** * 插入排序 * @param array 目标数组 */ public static void insertsort(int[] array) { //从第二个数据开始做循环,我们假定第一条数据已经在它应在的位置了 for(int i = 1;i < array.length;i++) { //取出目标位置的数值 int j = i; int target = array[i]; //对比目标位置的数值,与左侧排好序的数组比较,若发现有比目标值大的数,将比目标值大的数位置的数值往前提,游标后移 while(j > 0 && target < array[j - 1]) { array[j] = array[j - 1]; j--; } //跳出循环后将当前target插入游标位置 if(j != i) { array[j] = target; } } }
实现一个链表的反转。
public class node { private int index; private node next; public node(int index, node next) { this.index = index; this.next = next; } public int getindex() { return index; } public void setindex(int index) { this.index = index; } public node getnext() { return next; } public void setnext(node next) { this.next = next; } //非递归 public static node reverselist(node head) { node prev = null; while(head!=null){ node tmp = head.next; head.next = prev; prev = head; head = tmp; } return prev; } //递归 public static node reverselist2(node head) { if(head==null || head.next ==null) { return head; } node prev = reverselist2(head.next); head.next.next = head; head.next = null; return prev; } }
实现排序数组的二分查找。
public class searchutils { /** * 二分查找,递归 * @param array 目标数组 * @param target 查找内容 * @param low 查找起始位置 * @param high 查找结束位置 * @return 内容所在位置,-1代表不存在 */ public static int recursionbinarysearch(int[] array,int target,int low,int high) { if(low > high) { //起始位置大于结束位置,未找到,返回-1 return -1; } if(low == high) { //起始位置等于结束位置,判断是否等于目标值 if(array[low] == target) { return low; } else { return -1; } } int middle = (high + low)/2;//初始化中间位置 if(array[middle] > target) { return recursionbinarysearch(array,target,low,middle-1); } else if(array[middle] < target) { return recursionbinarysearch(array,target,middle+1,high); } else { return middle; } } /** * 二分查找,非递归 * @param array 目标数组 * @param target 查找内容 * @return 内容所在位置,-1代表不存在 */ public static int binarysearch(int[] array,int target) { int low = 0; int high = array.length - 1; int middle = 0; while(high > low) { middle = (high + low)/2;//获取中间位置 if(array[middle] > target) { high = middle - 1; } else if(array[middle] < target) { low = middle + 1; } else { return middle; } } if(array[low] == target) { return low; } else { return -1; } } }
实现二叉树的按层遍历。
/** * 按层遍历二叉树 * @param root 需要遍历的二叉树 */ public static void leveltree(treenode root) { if(root == null) return; queue queue = new linkedlist() ; queue.add(root); while(queue.size() != 0) { int len = queue.size(); for(int i=0;i