一、前言
以下不作为Android学习路径,只是汇总的社招Android客户端开发面试考点(因为还有笔试考点,后面结合在一起给大家学习路径),后续会为大家更新10w+字数的Android校招面试题库,还有其他岗位的相关题库和资料,想要什么岗位的可以留言哦~
本篇根据各个公司的面试问的问题的大数据进行总结,后面还会更新面试中考察所占比例,当然,本文只包括技术面,不包括hr面或者一些其他谈人生理想的。
二、Android面试知识框架
Android面试知识框架
三、Java 基础相关
3.1 数据结构与算法
3.1.1 常用的数据结构有哪些?
3.1.2 数组
(1).如何在一个1到100的整数数组中找到丢失的数字?
就是在这个使用程序找到100个元素数组中的缺失元素。正如我所说,知道这个技巧很好,它只需要你计算数字之和然后从实际总和中减去它,但是如果数组有多个缺失数字你就不能使用它。另一方面,BitSet解决方案更通用,因为您可以使用它在整数数组上查找多个缺失值。
(2).如何在给定的整数数组中找到重复的数字? 小米
解一、
最先涌现的想法是遍历一遍数组,用hash表记录每一个数字出现的次数;
用空间换时间
解二、
剑指offer解法
重新排序数组每个数字,当扫描到数字m的时候判断下标为i的数字是否等于m:如果是,就寻找下一个;如果不是,就判断下标为m的对应的数字是否等于m,如果它与第m个数字相等,就等于找到了一个重复的数字,如果不相等就把第i个数与第m个数交换位置,把m放在其对应的下标m的位置。
例如:
首先给定数组arr[] = {2, 3, 0, 1, 3}。因为数组中最大的数是n-1,那就一个萝卜一颗坑。从0号下标位置开始,0号元素为2,不等于0,交换0号和2号位置,数组变为:
{0, 3, 2, 1, 3}。再比较0号位置,下标和值相等,往后走到1号下标元素为3,不等于1,交换1号和3号,变成:{0, 1, 2, 3, 3}。再继续,下标来到4号位置,发现元素下标与值不相等,比较4号和3号下标位置,发现元素相等,返回3即可。
(3).如何在未排序整数数组中找到最大值和最小值? 字节跳动
关于这道题,我的第一个想法就是先自己设一个min 和max,然后遍历整数组。一个一个比较。如果某数比min小则将min赋值为该数,继续比较。
就像这样:
int min=100;
int max=0;
for(int i=0;i<n;i++)
{
if(num[i]<min)
min=num[i];
if(num[i]>max)
max=num[i];
}
(4).在Java中如何从给定数组中删除多重复制?
通过HashSet剔除
// 删除ArrayList中重复元素,add进去顺序就变了不考虑顺序的话可以使用
public static void removeDuplicate1(List list) {
HashSet h = new HashSet(list);
list.clear();
list.addAll(h);
System.out.println(list);
}
(5).大数相加(今日头条)
核心点考的是ASCII码和相加进位的问题。
比喻字符类型的'9'怎么转换成int的9?
'9' - '0' = 9。这个算法能理解吗?
char类型进行算数运算时是不是自动转换为int类型的了?
字符9的ASCII值是不是比字符0的多9个?这是第一个关键点。
第二个关键点是,注意相加时的进位。
对两个字符串的数字,可以使用字符数组的方式处理,也可以用StringBuffer。
有人会问,StringBuffer每次append都是在后面追加,但是处理数字进位时需要在前面处理。
其实StringBuffer有个方法reverse(),翻转字符串
举个例子比喻下整个处理过程:
String str1 = "123459";
string str2 = "123";
两个字符串需要翻转,为什么?
因为相加处理是从最右边的个位开始的,还有进位处理。
调用reverse()方法处理后:
String str1 = "954321";
string str2 = "321";
现在就好办了,个位对齐了。可以开始相加了,注意进位。
int carry = 0;
计算个位:
int value = str1.charAt(0) + str2.charAt(0) - 2*'0' + carry;
上面这行代码能理解吗?
翻译过来就是:'9' + '3' - 2*'0' + carry;
为什么 - 2*'0' ?
字符进行算术运算时,会转换成ASCII值在进行运算。
故继续翻译为:57 + 51 - 2*48 + 0;
是不是等于 9 + 3 + 0 ?
好,不多废话了。相加后的值为12。
直接把12存储在个位上吗?当然不是,把进位的10部分存储到carry变量中,便于进行十位数字相加时使用:
carry = 12 / 10;
value = 12 % 10;
然后把value的值保存到最终的个位上。
一次上述步骤。
最后需要注意的是,输入的两个字符串数字长度不一定相等。
第一次循环时要以较短的字符串未结束点,计算两个数字和carry的相加和进位。
然后在基于较长的字符串长出的部分循环,与carry相加,处理进位。
上面都把核心点说了,直接来撸代码吧,有注释的:
public static void main(String[] args) {
String str1 = "123459";
String str2 = "123";
System.out.println(add(str1, str2));//123582
}
private static String add(String str1, String str2) {
//任何一个字符串为null或空字符串,都不需要相加了
if (str1 == null || "".equals(str1)) {
return str2;
}
if (str2 == null || "".equals(str2)) {
return str1;
}
int maxLength = Math.max(str1.length(), str2.length());
//定义一个存贮结果的字符串,长度要比最大长度字符串还长一位,用于存储可能出现的进位
StringBuffer result = new StringBuffer(maxLength + 1);
//翻转两个字符串
str1 = new StringBuffer(str1).reverse().toString();
str2 = new StringBuffer(str2).reverse().toString();
//反转后的结果分别为:
//954321
//321
int minLength = Math.min(str1.length(), str2.length());
//进位
int carry = 0;
//当前位上的数值
int currentNum = 0;
//循环变量
int i = 0;
for (; i < minLength; i++) {
//分别获取两个字符对应的字面数值,然后相加,再加上进位
currentNum = str1.charAt(i) + str2.charAt(i) - 2 * '0' + carry;
//获取进位
carry = currentNum / 10;
//处理当前位的最终值
currentNum %= 10;
//保存当前位的值到最终的字符缓冲区中
result.append(String.valueOf(currentNum));
}
if (str1.length() < str2.length()) {
//选择
str1 = str2;
}
for (; i < str1.length(); i++) {
//分别获取两个字符对应的字面数值,然后相加,再加上进位
currentNum = str1.charAt(i) - '0' + carry;
//获取进位
carry = currentNum / 10;
//处理当前位的最终值
currentNum %= 10;
//保存当前位的值到最终的字符缓冲区中
result.append(String.valueOf(currentNum));
}
//处理最后一个的进位(当循环结束后,是不是还可能会有一个进位)
if (carry > 0) {
result.append(String.valueOf(carry));
}
//最后翻转恢复字符串,再返回
return result.reverse().toString();
}