京东android面试问题 面试 遇到的问题 怎么 解决

我的Android面试经验总结 - 安卓 - 伯乐在线
& 我的Android面试经验总结
“基础 Android 知识掌握的不错,学习能力也不错。但是基础知识部分比较薄弱,有些概念和逻辑掌握不清。” 感谢春林的这句话。
MVC,MVP 和 MVVM
MVC 通信方式,环形方式:
1、View 传送指令到 Controller
2、Controller 起到不同层面间的组织作用,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据 Model 上的改变。
3、Model 将新的数据发送到 View,用户得到反馈
所有通信都是单向的。
MVP 通信方式:
1、各部分之间的通信,都是双向的。
2、View 与 Model 不发生联系,都通过 Presenter 传递。
3、View 非常薄,不部署任何业务逻辑,称为”被动视图”(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。
MVVM 模式是 MVP 的升级:
基本上与 MVP 模式完全一致。唯一的区别是,它采用双向绑定:View的变动,自动反映在 ViewModel,反之亦然。
(以上内容取自:)
我们针对业务模型,建立的数据结构和相关的类,就可以理解为AndroidApp 的 Model,Model 是与 View 无关,而与业务相关的,例如数据库读取数据,应该是属于model层的事情。(感谢@Xander的讲解)
我的猜想:
至于为什么我们通常直接去在 Activity 中去写数据库数据读取,我的猜想是因为简单。试想,如果是为了规范,首先定义一个getDataFromDB()的接口,再写个类实现getDataFromDB()方法,以后如果改了请求数据所用的方法,直接改写实现类,听起来确实不错,可是仅仅是为了从数据库读点数据,额外添加了至少两个类文件真的有意义吗。
当然网络请求,是属于业务逻辑层C层。
MVP中 Presenter 真正需要处理的并非业务逻辑,而应该是视图逻辑。业务逻辑应该是视图无关的,可以是单独的一个类中,也可以是在P中。
P与V是一对多关系
EventBus应该作用于P层,在P层发送,在P层接收。
MVVM中,M层改变并不是直接改变V层,而是通过VM层去改变V层。M与V依旧是不直接操作的。
相关介绍:
架构的定义
有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计。
总结一下,就是一整个软件工程项目中的骨架,是一种宏观的规划。
Volley相关
Volley的磁盘缓存
在面试的时候,聊到 Volley 请求到网络的数据缓存。当时说到是 Volley 会将每次通过网络请求到的数据,采用FileOutputStream,写入到本地的文件中。
那么问题来了:这个缓存文件,是声明在一个SD卡文件夹中的(也可以是getCacheFile())。如果不停的请求网络数据,这个缓存文件夹将无限制的增大,最终达到SD卡容量时,会发生无法写入的异常(因为存储空间满了)。
这个问题的确以前没有想到,当时也没说出怎么回事。回家了赶紧又看了看代码才知道,原来 Volley 考虑过这个问题(汗!想想也是)
翻看代码DiskBasedCache#pruneIfNeeded()
private void pruneIfNeeded(int neededSpace) {
if ((mTotalSize + neededSpace)
mMaxCacheSizeInBytes) {
long before = mTotalS
int prunedFiles = 0;
long startTime = SystemClock.elapsedRealtime();
IteratorMap.EntryString, CacheHeader&& iterator = mEntries.entrySet().iterator();
while (iterator.hasNext()) {
Map.EntryString, CacheHeader& entry = iterator.next();
CacheHeader e = entry.getValue();
boolean deleted = getFileForKey(e.key).delete();
if (deleted) {
mTotalSize -= e.
//print log
iterator.remove();
prunedFiles++;
if ((mTotalSize + neededSpace)
mMaxCacheSizeInBytes * HYSTERESIS_FACTOR) {
1234567891011121314151617181920212223242526
private void pruneIfNeeded(int neededSpace) {&&&&if ((mTotalSize + neededSpace)&&mMaxCacheSizeInBytes) {&&&&&&&&return;&&&&}&&&&&long before = mTotalSize;&&&&int prunedFiles = 0;&&&&long startTime = SystemClock.elapsedRealtime();&&&&&IteratorMap.EntryString, CacheHeader&& iterator = mEntries.entrySet().iterator();&&&&while (iterator.hasNext()) {&&&&&&&&Map.EntryString, CacheHeader& entry = iterator.next();&&&&&&&&CacheHeader e = entry.getValue();&&&&&&&&boolean deleted = getFileForKey(e.key).delete();&&&&&&&&if (deleted) {&&&&&&&&&&&&mTotalSize -= e.size;&&&&&&&&} else { //print log&&&&&&&&}&&&&&&&&iterator.remove();&&&&&&&&prunedFiles++;&&&&&&&&if ((mTotalSize + neededSpace)&&mMaxCacheSizeInBytes * HYSTERESIS_FACTOR) {&&&&&&&&&&&&break;&&&&&&&&}&&&&}}
其中mMaxCacheSizeInBytes是构造方法传入的一个缓存文件夹的大小,如果不传默认是5M的大小。
通过这个方法可以发现,每当被调用时会传入一个neededSpace,也就是需要申请的磁盘大小(即要新缓存的那个文件所需大小)。首先会判断如果这个neededSpace申请成功以后是否会超过最大可用容量,如果会超过,则通过遍历本地已经保存的缓存文件的header(header中包含了缓存文件的缓存有效期、占用大小等信息)去删除文件,直到可用容量不大于声明的缓存文件夹的大小。
其中HYSTERESIS_FACTOR是一个值为0.9的常量,应该是为了防止误差的存在吧(我猜的)。
Volley缓存命中率的优化
如果让你去设计Volley的缓存功能,你要如何增大它的命中率。可惜了,如果上面的缓存功能是昨天看的,今天的面试这个问题就能说出来了。
还是上面的代码,在缓存内容可能超过缓存文件夹的大小时,删除的逻辑是直接遍历header删除。这个时候删除的文件有可能是我们上一次请求时刚刚保存下来的,屁股都还没坐稳呢,现在立即删掉,有点舍不得啊。
如果遍历的时候,判断一下,首先删除超过缓存有效期的(过期缓存),其次按照LRU算法,删除最久未使用的,岂不是更合适?
Volley缓存文件名的计算
这个是我一直没弄懂的问题。
如下代码:
private String getFilenameForKey(String key) {
int firstHalfLength = key.length() / 2;
String localFilename = String.valueOf(key.substring(0, firstHalfLength).hashCode());
localFilename += String.valueOf(key.substring(firstHalfLength).hashCode());
return localF
private String getFilenameForKey(String key) {&&&&int firstHalfLength = key.length() / 2;&&&&String localFilename = String.valueOf(key.substring(0, firstHalfLength).hashCode());&&&&localFilename += String.valueOf(key.substring(firstHalfLength).hashCode());&&&&return localFilename;}
为什么会要把一个key分成两部分,分别求hashCode,最后又做拼接。
这个问题之前在stackoverflow上问过
原谅我,别人的回答我最初并没有看懂。直到最近被问到,如果让你设计一个HashMap,如何避免value被覆盖,我才想到原因。
先来看一下 String#hashCode() 的实现:
@Override public int hashCode() {
int hash = hashC
if (hash == 0) {
if (count == 0) {
final int end = count +
final char[] chars =
for (int i = ++i) {
hash = 31*hash + chars[i];
hashCode =
123456789101112131415
@Override public int hashCode() {&&&&int hash = hashCode;&&&&if (hash == 0) {&&&&&&&&if (count == 0) {&&&&&&&&&&&&return 0;&&&&&&&&}&&&&&&&&final int end = count + offset;&&&&&&&&final char[] chars = value;&&&&&&&&for (int i = offset; i&&end; ++i) {&&&&&&&&&&&&hash = 31*hash + chars[i];&&&&&&&&}&&&&&&&&hashCode = hash;&&&&}&&&&return hash;}
从上面的实现可以看到,String的hashcode是根据字符数组中每个位置的字母的int值再加上上次hash值乘以31,这种算法求出来的,至于为什么是31,我也不清楚。
但是可以肯定一点,hashcode并不是唯一的。不信你运行下面这两个输出:
System.out.print("======" + "vFrKiaNHfF7t[9::E[XsX?L7xPp3DZSteIZvdRT8CX:w6d;v.hashCode());
System.out.print("======" + "hI4pFxGOfS@suhVUd:mTo_begImJPB@Fl[6WJ?ai=RXfIx^=Aix@9M;;?Vdj_Zsi".hashCode());
System.out.print("======" + "vFrKiaNHfF7t[9::E[XsX?L7xPp3DZSteIZvdRT8CX:w6d;v.hashCode());System.out.print("======" + "hI4pFxGOfS@suhVUd:mTo_begImJPB@Fl[6WJ?ai=RXfIx^=Aix@9M;;?Vdj_Zsi".hashCode());
这两个字符串是根据hashcode的算法逆向出来的,他们的hashcode都是12345。逆向算法请见
再回到我们的问题,为什么会要把一个key分成两部分。现在可以肯定的答出,目的是为了尽可能避免hashcode重复造成的文件名重复(求两次hash两次都与另一个url重复的概率总要比一次重复的概率小吧)。
顺带再提一点,就像上面说的,概率小并不代表不存在。但是Java计算hashcode的速度是很快的,应该是在效率和安全性上取舍的结果吧。
推送心跳包是TCP包还是UDP包或者HTTP包
其实聊起这个问题是因为最近看到
同学写的一篇文章《》结果就产生了这个没回答出来的问题(妈蛋,自己给自己挖坑 – -)
最后看了这篇文章(好像是转的,没找到原地址)
原来心跳包的实现是调用了socket.sendUrgentData(0xFF)这句代码实现的,所以,当然是TCP包。
ARGB_8888占用内存大小
首先说说本题的答案,是4byte,即ARGB各占用8个比特来描述。当时回答错了,详细解答看这里
这个问题引出了一个大大的闹剧,请听我慢慢道来。
不知道怎么就聊到 Bitmap 压缩上了,他说他们的Bitmap居然都是不压缩的
还是直接甩代码吧。。。。
public static Bitmap create(byte[] bytes, int maxWidth, int maxHeight) {
//上面的省略了
option.inJustDecodeBounds =
BitmapFactory.decodeByteArray(bytes, 0, bytes.length, option);
int actualWidth = option.outW
int actualHeight = option.outH
// 计算出图片应该显示的宽高
int desiredWidth = getResizedDimension(maxWidth, maxHeight, actualWidth, actualHeight);
int desiredHeight = getResizedDimension(maxHeight, maxWidth, actualHeight, actualWidth);
option.inJustDecodeBounds =
option.inSampleSize = findBestSampleSize(actualWidth, actualHeight,
desiredWidth, desiredHeight);
Bitmap tempBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, option);
if (tempBitmap != null
& (tempBitmap.getWidth() & desiredWidth || tempBitmap
.getHeight() & desiredHeight)) {
bitmap = Bitmap.createScaledBitmap(tempBitmap, desiredWidth,
desiredHeight, true);
tempBitmap.recycle();
bitmap = tempB
123456789101112131415161718192021222324252627282930
public static Bitmap create(byte[] bytes, int maxWidth, int maxHeight) {
//上面的省略了&&&&&&&&option.inJustDecodeBounds = true;&&&&&&&&BitmapFactory.decodeByteArray(bytes, 0, bytes.length, option);&&&&&&&&int actualWidth = option.outWidth;&&&&&&&&int actualHeight = option.outHeight;&&&&&&&&&// 计算出图片应该显示的宽高&&&&&&&&int desiredWidth = getResizedDimension(maxWidth, maxHeight, actualWidth, actualHeight);&&&&&&&&int desiredHeight = getResizedDimension(maxHeight, maxWidth, actualHeight, actualWidth);&&&&&&&&&option.inJustDecodeBounds = false;&&&&&&&&option.inSampleSize = findBestSampleSize(actualWidth, actualHeight,&&&&&&&&&&&&&&&&desiredWidth, desiredHeight);&&&&&&&&Bitmap tempBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, option);&&&&&&&&&// 做缩放&&&&&&&&if (tempBitmap != null&&&&&&&&&&&&&&&&& (tempBitmap.getWidth() & desiredWidth || tempBitmap&&&&&&&&&&&&&&&&.getHeight() & desiredHeight)) {&&&&&&&&&&&&bitmap = Bitmap.createScaledBitmap(tempBitmap, desiredWidth,&&&&&&&&&&&&&&&&&&&&desiredHeight, true);&&&&&&&&&&&&tempBitmap.recycle();&&&&&&&&} else {&&&&&&&&&&&&bitmap = tempBitmap;&&&&&&&&}&&&&}&&&&&return bitmap;}
你这么做,decodeByteArray两次不是更占内存吗?第一次设置inJustDecodeBounds = true 时候是不占内存的,因为返回的是null
一脸不相信我的说:噢,这地方我下去再看看。吓得我回来了以后赶紧又看了看,还好没有记错,见源码注释
* If set to true, the decoder will return null (no bitmap), but
* the out... fields will still be set, allowing the caller to query
* the bitmap without having to allocate the memory for its pixels.
public boolean inJustDecodeB
/** * If set to true, the decoder will return null (no bitmap), but * the out... fields will still be set, allowing the caller to query * the bitmap without having to allocate the memory for its pixels. */public boolean inJustDecodeBounds;
Activity中类似onCreate、onStart运用了哪种设计模式,优点是什么
这个回答的太多了,我当时说的是代理模式,因为AppCompatActivity中的确是使用的代理模式。这一点还要感谢 当时说让我看看AppCompatDelegate类的设计。其主要目的就是通过使用组合来替代继承,降低了耦合。
不过回家后再想一想,对方想听到的应该是模板方法模式吧。在父类中实现一个算法不变的部分,并将可变的行为留给子类来实现。生命周期方法原本就是在基类中做出了Activity不同状态时回调的一系列方法,而这些方法具体需要做的可变部分交给子类去完成。
HashMap的底层实现
HashMap内部是通过数组实现的,诶,大学时候数据结构有讲过啊,都忘记了。根据hash算法,求出当前key应该存放在数组的那个index处,如果有值了,则存在相邻的下一个位置。
根据如果自己实现HashMap如何防止value覆盖。同上面 Volley 中讲到的。
Atomic、volatile、synchronized区别
面Java基础的时候遇上了这个问题,说如果只有一个i++;的时候,volatile和synchronized能否互换。当时也不知道,感觉volatile作为修饰变量的时候,变量自加会出现加到一半发生线程调度。再看看当时蒙对了。
volatile 可以保证在一个线程的工作内存中修改了该变量的值,该变量的值立即能回显到主内存中,从而保证所有的线程看到这个变量的值是一致的。但是有个前提,因为它不具有操作的原子性,也就是它不适合在对该变量的写操作依赖于变量本身自己。就比如i++、i+=1;这种。但是可以改为num=i+1;如果i是一个 volatile 类型,那么num就是安全的,总之就是不能作用于自身。
synchronized是基于代码块的,只要包含在synchronized块中,就是线程安全的。
既然都说了线程安全,就多了解几个:
AtomicInteger,一个轻量级的synchronized。使用的并不是同步代码块,而是Lock-Free算法(我也不懂,看代码就是一个死循环调用了底层的比较方法直到相同后才退出循环)。最终的结果就是在高并发的时候,或者说竞争激烈的时候效率比synchronized高一些。
ThreadLocal,线程中私有数据。主要用于线程改变内部的数据时不影响其他线程,使用时需要注意static。详细分析见 。
再补一个,才学到的。利用clone()方法,如果是一个类的多个对象想共用对象内部的一个变量,而又不想这个变量static,可以使用浅复制方式。(查看设计模式原型模式)
做内部库设计时,最重要的考虑是jar的成本,方法数、体积。
设计模式不应该是去记忆,而应该是用的时候自然而然的用上。
3月11日更新
面试真的是有够烦的,因为题目是随机的,而知识是无穷的。直到被很多答案都是没有标准的。就好像上面提到的 MV* ,也许到现在上面的理解依旧有问题,但是我觉得架构是死的,而最合适的才是最好的。
但是有一点,面试也是一种学习,至少它能让你知道你的薄弱点在哪。
可能感兴趣的话题
社招吗?我还没参加过社招,有点紧张。校招倒是经历挺多的。
关于安卓频道
安卓频道分享Android开发文章,精选工具和安卓相关的行业动态。
新浪微博:
推荐微信号
(加好友请注明来意)
– 好的话题、有启发的回复、值得信赖的圈子
– 分享和发现有价值的内容与观点
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 翻译传播优秀的外文文章
– 国内外的精选文章
– UI,网页,交互和用户体验
– 专注iOS技术分享
– 专注Android技术分享
– JavaScript, HTML5, CSS
– 专注Java技术分享
– 专注Python技术分享
& 2017 伯乐在线重要提示:看了本文的人还对以下公司做了评价!
同事之间相处融洽,没有太多的办公室政治。…
工作辛苦,加班多,待遇好…
2016年android应用开发岗位跳槽面试常问问题的总结
更新时间:&&&&&&&&
来源:网络&&&&&&&&
【看准网()】Android面试题频道小编搜集的范文“2016年android应用开发岗位跳槽面试常问问题的总结”,供大家阅读参考,查看更多相关面试题目 ,请访问Android面试题频道。
1.简单的设计模式:单例模式:在系统中一个类只有一个实例。 分为懒汉模式和饿汉模式。饿汉模式的代码如下:public class Singleten{private static singleten Instance = new Singleten();private Singleten(){}public static getInstance(){return I}}观察者模式:一个对象改变状态,则依赖它的所有对象都会得到通知并改变状态。迭代器模式:iterator();遍历元素的方法有hasNext(),first(),next(),remove()模版方法2.Listview列表效率优化(1)利用convertview回收视图(2)采用ViewHolder模式(3) 异步加载图片(4) 快速滑动时不加载图片(5) 如果自定义的item中有图片,需要处理图片(减少图片所占内存)1.对图片进行边界压缩 2.用option类来保存图片大小 3.避免图片的实时缩放,最好预先缩放到视图大小(6)尽量避免在listview适配器中使用线程,因为线程是产生内存泄露的主要原因在于线程的生命周期不可控。3.应用内存优化(1)bitmap设置图片大小(优化内存溢出)BitmapFactory.Option option = new BitmapFactory.Option();option.inSampleSize = 2; //将视图宽、高都变为原来的1/2(2)bitmap对象销毁,可以借助recycle()方法让GC回收bitmap对象。(3)尽量避免static成员变量引用资源消耗过多的实例,如:context(4)使用Application的context(5)及时关闭资源,如在查询数据库时需要及时关闭cursor(6)对经常使用的图片使用软引用保存(7)线程也是造成内存泄露的一个重要原因,在于线程的生命周期不可控制,解决方法:1.将线程内部类改为静态内部类2.用弱引用来保存context引用(8)使用.9图片4.Handler与Handler Thread关系android消息处理机制:handler、Looper、MessageQueue、Message将一个线程变为looper线程的方法: Looper. //初始化MessageQueue与LooperLooper.loop();//消息循环5.异常处理IoException异常是编译器异常,在编译时就会报错ANR异常解决方法:尽量在主线程只做少量工作,比较耗时的工作单独在一个子线程中完成(或使用异步请求)6.数据库的优化1.使用索引2.使用事务3.查询时返回更少的结果集和字段7.数据存储的方法sharedpreference存储、文件存储、SQLite存储、contentprovide存储、网络存储数据8.启动服务的两种方法:startservice 和bindservice使用startservice()启动服务,调用者和服务之间没有关联,即使调用者退出了,服务仍然运行;使用bindservice()启动服务,调用者和服务绑定在一起,调用者一旦退出,服务也终止;采用startservice启动服务,只能调用stopservice终止服务。startservice()启动服务的生命周期:oncreat()、onstart(),ondestroy() ;第一次startservice()启动服务会调用oncreat()、onstart();后面再使用startservice()启动服务,只会调用onstart()bindservice()启动服务的生命周期:oncreat()、onbind()、omunbind()、ondestroy();第一次 bindservice()启动服务调用oncreat()、onbind(),多次调用 bindservice()并不会多次创建服务及绑定,如果调用者希望与正在绑定的服务解除绑定,可以调用unbindservice()方法。8.set、List的区别:Set中元素不重复9.contentprovide如何实现数据共享如果想使应用程序的数据公开化:1.自己创建一个contentprovide 2.将数据添加到一个已经存在的contentprovide上如何获取数据: 外界程序可以通过contextResolver接口访问contentprovide提供的数据contentprovide的优点为:为其他程序提供了一个对数据访问的接口,从而实现对数据进行访问和更新的操作1.在某个activity界面按Home键走的生命周期:onpause(),onstop(),onsaveinstanceState()在某个activity界面按Home键再点击应用图标走的生命周期:onRestart().onStart(),onResume()11.在android中的4种Activity启动模式:SingleTask、standard、SingleTop、SingleInstance12.Http协议 HttpClient类 Jeson包解析13.socket协议android客户端实现:try{socket = new Socket(̶192.168.1.32″,1989);InputStream inputStream = new FileInputStream (̶e://a.txt”);OutputStream outputStream = socket.getoutputStream() ;byte buffer[] = new byte[4*124];int temp = ;while((temp = inputStream .read(buffer))!=-1){outputStream.write(buffer,,temp);}outputStream.flush();}服务器端:try{serverSocket = new serverSocket (989);Socket socket = serverSocket.accept();InputStream inputStream = new FileInputStream (̶e://a.txt”);InputStream inputStream = socket.getinputStream() ;byte buffer[] = new byte[4*124];int temp = ;while((temp = inputStream .read(buffer))!=-1){system.out.println(new String(buffer,,temp));}serverSocket.close();}14.AIDL android内部进程通信接口的描述语言15.强引用:内存不足时,不会回收强引用的对象软引用:内存不足时,会回收软引用的对象弱引用:垃圾回收每次都会回收弱引用的对象16.android view的刷新机制17.静态内部类(1)非静态内部类中bunengdingy静态成员变量和方法(2)外部类和非静态内部类之间可以互相访问自己的私有成员(3)静态内部类只能访问外部类的静态成员
看了这篇文章的还看了
大学法学专业寒假社会实践报告 作为一名法学专业的学生,我时常感到迷茫。对于自己在大学已经一年有余的学习,有时真不清楚自己学到了多少,也许身在其中便是一个成长的过程。 但我知道我不会总是那个曾经永远长不大的孩子,因为我发现自己的视野将愈加远倾。也许出生于南方的我与好...…
珍惜地球资源建议书亲爱的同学们:你们好!我是一个跟你们差不多大年纪的学生,今年刚上六年级。我们同在一个地球上,同在一片蓝天下,珍惜地球资源是我们的责任。我们都知道,地球是我们赖以生存的地方。宇宙中,以地球为中心的四十万亿千米的范围里,没有适合人类居住的另一个星球...…
小学生关于环境污染的建议书尊敬的校长:您好!我是您学校的一名学生,今天我想和您谈谈关于学校环境污染的问题。以前,校园环境优美,绿树成荫,小鸟整天叽叽地叫。这样的校园,是个学习的好地方。可如今:每当吃完包点,就会看到满地乱扔的包点,牛奶盒。清洁工人刚打扫完,就又有人...…
保护长城建议书同学们:我国历史悠久,古迹众多。但由于种种原因,许多古迹遭到严重的破坏。比如长城,游人大量涌入,长城的城墙被乱涂乱画,果皮、塑料袋等垃圾随处可见,有些村民在垛口处私自搭梯子,收点小费等等。看见这些令人担忧的情景,我们也许十几年后地就看不见长城了,我...…
关于工厂排放污水的建议书荆门石化总厂:现在竹皮河的水又脏又臭。每当人们走在竹皮河边时,总会闻到一股臭气。人们都捂着鼻子,加快步伐。想想以前,竹皮河的水十分干净和清澈。听爷爷说:&从河东走到河西一眼望去就有十几筐的大乌龟。&可现在呢?一只也没见到了。由于现在几十个...…
面试题目热门标签
友情链接链接合作QQ:问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
最近发现一个比较好的方法,
首先看他用的是否是android手机,品质如何,然后借过来扫一眼他常用的应用,简单聊下他对这些应用的看法,之后打开一个常见应用,找到一个界面或者功能点问下他的实现思路,比如网易新闻客户端主页的幻灯片效果如何实现等,这样就能挺好地了解他对业界的关注程度和技术功底了。
不知道大家有没有什么更好的方法呢?
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
我觉得面试程序员不应该只是局限于他会做什么,面试JAVA开发不应该只看他对SSH架构等的了解程度,面试C开发不应该只看他对指针,内存控制等的了解程度...
当然,也不能一概而论...
首先需要明确你们需要招聘什么档次的程序员,然后根据你的目标定位采取相应的策略才有意义。你非考察一个中高级程序员C的基础知识,那只是在考察谁在面试前准备的充分而已。
初级程序员,主要考察学习能力,是不是足够聪明以及对开发工作的热情程序。因为这部分人主要以培养为主,培养的基础并非掌握了多少知识,而是有多大的潜力。
中级程序员,主要考察他对于技术理解的深度或者宽度。他可以足够专,也可以足够广,但总得有点什么。考察的方式可能更多的不是听他说什么,而是看他都做了什么。github, blog, 各种社区论坛,读过什么书,做过什么项目。当然深度和广度的考察方式不太相同。但无论怎样,目的都是更多的去了解这个人的能力。推荐一篇文章
高级程序员,不知道.....
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
其实我觉得android开发其实难度不大,如果面试一个人,我觉得主要看他的编程能力,其次是对android的了解,我不建议去询问coder对某个api的熟悉程度,可以大概的询问他对某些场景的实现思路。
同步到新浪微博
分享到微博?
Hi,欢迎来到 SegmentFault 技术社区!⊙▽⊙ 在这里,你可以提出编程相关的疑惑,关注感兴趣的问题,对认可的回答投赞同票;大家会帮你解决编程的问题,和你探讨技术更新,为你的回答投上赞同票。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
扫扫下载 App}

我要回帖

更多关于 android开发遇到问题 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信