本帖最后由 西安-就业部 于 2016-4-24 17:53 编辑
阿里体验卡已充值,小灰灰带你体验变态社招
(参与面试者:就业部-小灰灰)
前言:对于阿里自己曾经有一份不甘心,也因为这个才有了我和传智播客、黑马程序员的缘分,这次参加阿里社招面试首先是大学同学内推的,他在阿里天猫做大数据的,有内推的名额。经过十多天的艰辛历程,最后终于啃下了阿里的offer,这对我来讲十分有意义,校招的时候因为没有一点的android基础倒在了技术二面,去了深圳黑马苦练一番,然后经过一年工作时间的积累,最终还是达成目标,心满意足了。不扯皮了,下面整点硬菜了。
1. 面试情况
【面试公司】阿里巴巴集团天猫事业部 【面试结果】拿到offer(16K+五险一金+年终奖) 【面试时间】2016/3/29 -- 2016/4/5
2. 笔试题目
由于参加的是在线笔试的缘故,下面题目全部凭印象记得,有些题百度找到了原型,有些就只能记个大概了。
1、设有一个顺序栈S,元素s1、s2、s3、s4、s5、s6依次进栈,如果6个元素的出栈顺序为s2、s3、s4、s6、s5、s1,则顺序栈的容量至少应为多少?
A、2 B、3 C、4 D、5
2、给定如下代码: int x[4]={0}; int y[4]={1}; 数组x和y的值为()
A、{0,0,0,0},{1,1,1,1}
B、{0,0,0,0},{1,0,0,0}
C、{0,不确定},{1,不确定}
D、与编译器相关
3、假设在n进制下,下面的等式成立,n值是() 567*456=150216
A、9 B、10 C、12 D、18
4、在排序方法中,元素比较次数与元素的初始排列无关的是()
A、Shell 排序 B、归并排序 C、直接插入排序 D、选择排序
5、(he)的平方=she。h、e、s代表的数字?分别代表2、5、6
6、一个完全二叉树有770个节点,那么其叶子的个数为:385
7、 2的32次方是多少?
解答:这个题目我当时不知道咋写,最后用二进制表示了。
100000000000000000000000000000000
8、假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈。假如:n = 5 , m = 3 , r = {{1 , 2} , {2 , 3} , {4 , 5}},表示有5个人,1和2是好友,2和3是好友,4和5是好友,则1、2、3属于一个朋友圈,4、5属于另一个朋友圈,结果为2个朋友圈。
解答:这个题目属于数据结构中并查集的应用,不懂并查集的可以找度娘帮忙!
- public class Test {
- private int[] set = new int[1000];
- public int find(int x) { // 带路径优化的并查集查找算法
- int i, j, r;
- r = x;
- while (set[r] != r)
- r = set[r];
- i = x;
- while (i != r) {
- j = set[i];
- set[i] = r;
- i = j;
- }
- return r;
- }
- public void merge(int x , int y){ //优化的并查集归并算法
- int t = find(x);
- int h = find(y);
- if(t < h)
- set[h] = t;
- else
- set[t] = h;
- }
- int friends(int n , int m , int[][] r){
- int i , count;
- for(i = 1 ; i <= n ; ++i) //初始化并查集,各点为孤立点,分支数为n
- set[i] = i;
- for(i = 0 ; i < m ; ++i)
- merge(r[i][0] , r[i][1]);
- count = 0;
- for(i = 1 ; i <= n ; ++i)
- {
- if(set[i] == i)
- count++;
- }
- return count;
- }
- public static void main(String[] args) {
- System.out.println(new Test().friends(5, 3, new int[][]{{1,2},{2,3},{4,5}}));
- }
复制代码
9、ID为TMao的淘宝用户前些日子在淘宝机器人网店购买了一个智能机器人oz.这个机器人不仅精致小巧,还具有很多有意思的功能。比如:oz可以在迷宫里自由的上下左右走动; 并且,在不碰到障碍物的情况下,它能够以最短时间从入口处走到出口 (假设存在的话); 最智能的是,在有充电器的地方oz还可以给自己充电 。
现在,TMao设计了很多种迷宫,并且在里面随意的摆了些充电器,想请你们帮他算下,这个智能机器人要多久时间可以走出去呢?
他做了如下假设:
1.迷宫可以看作是长为w,宽为h的网格;
2.机器人每移动一步,需要时间1s,消耗电量0.5格;
3.机器人初始电量为满格4格;
4.每个充电器充电次数不限 (充电时间所需时间忽略不计),机器人可以反复经过一个地方,但是不能走到有障碍的地方,并且一旦机器人电量变为0,它就只能停下来,哪怕这个位置正好有充电器,它也没有足够的电量去执行充电操作;
5.机器人走到迷宫出口,必须至少还有0.5格电量,否则也算没走出出口。
输入:
第一行输入w,h分别表示迷宫的长和宽(w , h <= 10)。
接下来的h行表示迷宫的布局:-1表示该位置是障碍物, 0表示该位置什么也没有,1表示迷宫入口, 2表示迷宫出口, 3表示该位置有充电器。
输出:
输出机器人oz走到出口处的时间;如果无法按要求走到出口则输出”Pity oz!”。
解答:这种类似题目我之前就写过很多,这道题属于图论里的搜索问题,不过他加了一些限制条件。就是每次到了一个新的充电地方就可以以饱满的电量继续前进。所以就先从起点开始找。每次到了一个充电点且比以前的路劲更优的话就可以更新路径。把这个点继续入队列,下一次又从这一个点开始BFS(广度优先搜索)。直到全部搜索完毕,这题要用到优先队列,当时对java的优先队列还不熟悉,直接用了C++ STL模板库了,所以下面是c++代码,不过差不多都一样。
- #include<cstdio>
- #include<cstring>
- #include<cstdlib>
- #include<queue>
- using namespace std;
- int map[13][13];
- int minpath[13][13]; //用来存放从原点到这一步i,j的最小步数。
- int row,col;
- int endi,endj;
- int dir[][2] = {{-1,0},{0,-1},{1,0},{0,1}};
- struct node
- {
- int x,y;
- int pu; //真正的步数
- int p; //电池的数字用1~7表示
- bool operator < (const node& a)const
- {
- return p>a.pu;
- }
- };
- priority_queue<node> pq; //优先队列必不可少,
- int Min(int a,int b)
- {
- return a>b?b:a;
- }
- void BFS(struct node no)
- {
- queue <node> q;
- q.push(no);
- struct node var;
- while(!q.empty())
- {
- no = q.front();
- q.pop();
- if(map[no.x][no.y]==2)
- minpath[no.x][no.y] = Min(minpath[no.x][no.y],no.pu);
- if(map[no.x][no.y]==3 && no.pu<minpath[no.x][no.y])//每次找到充电点还要判断他是否是比上一次更优
- {
- minpath[no.x][no.y] = no.pu;
- var = no;
- var.p = 0; //每次找到一个充电点就把充电归零
- pq.push(var); //每次找到一个充电点就要把它入队列。。核心核心
- }
- for(int i=0;i<4;i++)
- {
- int x = no.x+dir[i][0];
- int y = no.y+dir[i][1];
- if(map[x][y]!=-1 && no.p<7) //不能到7,到7就是只有0.5电量,不能进行下一步了
- {
- var.x = x;
- var.y = y;
- var.pu = no.pu+1;
- var.p = no.p+1;
- q.push(var);
- }
- }
- }
- }
- int main()
- {
- int i,j;
- while(scanf("%d%d",&col,&row) && row+col!=0)
- {
- struct node no;
- memset(map,-1,sizeof(map));
- memset(minpath,0x3f,sizeof(minpath));
- while(!pq.empty())
- pq.pop();
- for(i=1;i<=row;i++)
- for(j=1;j<=col;j++)
- {
- scanf("%d",&map[i][j]);
- if(map[i][j]==1)
- {
- no.x = i;
- no.y = j;
- no.p = no.pu = 0;
- pq.push(no);
- }
- if(map[i][j]==2)
- {
- endi = i;
- endj = j;
- }
- }
- while(!pq.empty())
- {
- no = pq.top();
- pq.pop();
- BFS(no);
- }
- if(minpath[endi][endj]!=minpath[0][0]) //minpath[0][0]一直没有变化,所以和它比
- printf("%d\n",minpath[endi][endj]);
- else
- printf("Pity oz!\n");
- }
- return 0;
- }
复制代码
10、假设有一个硬币,抛出字(背面)和花(正面)的概率都是0.5,而且每次抛硬币与前次结果无关。现在做一个游戏,连续地抛这个硬币,直到连续出现两次字为止,问平均要抛多少次才能结束游戏?注意,一旦连续抛出两个“字”向上游戏就结束了,不用继续抛。
解答:这题目当时我也是搞了半天一点头绪没有,事后在网上找到了答案(数学不好的建议忽略不看,保智商要紧)
点击查看答案 http://www.cnblogs.com/atyuwen/archive/2010/09/12/coin.html
3. 面试经过
刚开始都是互相介绍一下,问了我一些个人问题,这里就不多说了,直接进入正题!
Q: 按照简历你毕业才半年多的时候,怎么工作年限你写的1年呢?
A: 是这样的,当初阿里校招的时候我也应聘Android开发,但因为没有一点开发经验,二面就被刷了,之后自己自学了一段Android时间,就去深圳进入泰捷公司,在泰捷的一年我觉得自己成长了很多,学到了很多Android开发技巧,掌握了主流Android的开发技术。但去阿里这个大平台学习和发展一直是我的梦想,所以当我觉得自己技术可行的时候,我就再次来试试了。
Q: 你项目里面提到了应用Glide图片加载框架,能详细叙述一下吗?
A:现在的Android开发中主流的图片加载框架主要有Glide、Picasso、Fresco等,当然也存在一些比较老的框架如Universal-ImageLoader、XUtils等。其实Picasso这个库我用的时间最长,它有以下特性:
- 处理Adapter中的 ImageView 回收和取消已经回收ImageView的下载进程
- 使用最少的内存完成复杂的图片转换,比如把下载的图片转换为圆角等
而Gilde是在最近的一个项目中用到的,但我对它也是比较熟悉的了,Glide具有获取、解码和展示视频剧照、图片、动画等功能,它还有灵活的API,这些API使开发者能够将Glide应用在几乎任何网络协议栈里。Glide可以实现平滑的图片列表滚动效果,支持远程图片的获取、大小调整和展示。15年的时候,Glide 3.0发布,这个版本包括很多新功能,如
- Activity 与Fragment生命周期的集成,可以智能的暂停和重新开始请求;
- OkHttp 和Volley 的支持等,Glide默认选择HttpUrlConnection作为网络协议栈,当然我们也还可以选择OkHttp和Volley作为网络协议栈;
最后还有一个Fresco,它是FaceBook主推的图片加载框架。我在平时学习中应用过,但项目中还未具体应用。它实现了图片的渐进式呈现,渐进式的JPEG图片格式已经流行数年了,渐进式图片格式先呈现大致的图片轮廓,然后随着图片下载的继续,呈现逐渐清晰的图片,这对于移动设备,尤其是慢网络有极大的利好,可带来更好的用户体验,同时它也支持对Gif图和WebP格式图的加载。
Q:你刚才提到了OKHttp,你对OKHttp有什么了解,做过okhttp的封装吗?
A:我负责开发的游戏中心,网络请求框架用的就是Volley+OkHttp,Volley 默认根据 Android 系统版本使用不同的 Http 传输协议实现.在 Android 2.3以下使用 ApacheHttpStack 作为传输协议, 在 3.0 及以下使用 HttpURLConnection 作为传输层协议。而OkHttp 相较于其它的实现有以下的优点.
- 支持SPDY,允许连接同一主机的所有请求分享一个socket。
- 当网络出现问题的时候,OKHttp会依然有效,它将从常见的连接问题当中恢复。
- 如果服务端有多个IP地址,当第一个地址连接失败时,OKHttp会尝试连接其他的地址,这对IPV4和IPV6以及寄宿在多个数据中心的服务而言,是非常有必要的。
因此使用 OkHttp 作为替代是好的选择.使用也非常简单,首先用 OkHttp 实现一个新的 HurlStack 用于构建 Volley 的 requestQueue. 然后使用 OkHttpStack 创建新的 Volley的 requestQueue.即可。
Q:简历上你写的熟悉c/c++,但你是做Android开发的,应该对java更熟悉吧?
A:是这样的,我大学主要学的c和c++,用来搞Acm的,毕业之后虽然一直在从事Android开发,但每周都会抽时间去刷刷题,用的就是c/c++。相比较而言,现在可能对java更熟悉,其实使用哪种开发语言都不是很重要,重要的是掌握解决问题的思想,因为搞过Acm,所以特别喜欢琢磨问题。刚开始做项目的时候,在项目开发中常会用到一些第三方框架,但我不会直接拿来使用,一般都是先学习别人框架的思想和代码,然后写出自己的工具类,并分享出去,比如Andorid的图片加载三级缓存(内存、本地、网络),内存缓存用到了LruCache,这个类内部实现了对BitMap的LRU算法管理,我参考了LruCache类,用LRU算法对本地磁盘的图片数据也进行了管理。之后才发现,原来国外大牛早已经写了DiskLruCache类,又拿过来学习了一番,收获颇多。
大的问题就这几个,我面试有个习惯,喜欢把一个技术点做深度剖析,而这一点很迎合大公司对面试者技术点考察要求,几个问题过后,面试官就不在发难提问了,面试话题也从开始的技术提问转移到国内直播平台的讨论,屌丝间的话题大家都懂,挺High的。
4. 面试总结
大公司真是不给活路啊,怎么社招都这么变态的,对于应聘者的编程基础要求很高,不过也符合大公司对技术人员的要求。所以,各位童鞋们,加油吧!
|