《安卓应用开发常见笔试面试题目(共35页).docx》由会员分享,可在线阅读,更多相关《安卓应用开发常见笔试面试题目(共35页).docx(35页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上Android笔试总结1.请谈一下Android系统的架构。答:Android系统采用了分层架构,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。2.谈谈android大众常用的五种布局。答:在Android中,共有五种布局方式,分别是:FrameLayout(框架布局),LinearLayout (线性布局),AbsoluteLayout(绝对布局),RelativeLayout(相对布局),TableLayout(表格布局)。(1)FrameLayout 框架布局,放入其中的所有元素都被放置在最左上的区域,而且无法为这些元素指定一个确
2、切的位置,下一个子元素会重叠覆盖上一个子元素,适合浏览单张图片。(2)LinearLayout 线性布局,是应用程序中最常用的布局方式,主要提供控件水平或者垂直排列的模型,每个子组件都是以垂直或水平的方式来定位.(默认是垂直)(3)AbsoluteLayout 绝对定位布局,采用坐标轴的方式定位组件,左上角是(0,0)点,往右x轴递增,往下Y轴递增,组件定位属性为android:layout_x 和 android:layout_y来确定坐标。(4)RelativeLayout 相对布局,根据另外一个组件或是顶层父组件来确定下一个组件的位置。和CSS里面的类似。(5)TableLayout 表
3、格布局,类似Html里的Table.使用TableRow来布局,其中TableRow代表一行,TableRow的每一个视图组件代表一个单元格。3.谈谈android数据存储方式。答:Android提供了5种方式存储数据:(1)使用SharedPreferences存储数据;它是Android提供的用来存储一些简单配置信息的一种机制,采用了XML格式将数据存储到设备中。只能在同一个包内使用,不能在不同的包之间使用。(2)文件存储数据;文件存储方式是一种较常用的方法,在Android中读取/写入文件的方法,与Java中实现I/O的程序是完全一样的,提供了openFileInput()和openFi
4、leOutput()方法来读取设备上的文件。(3)SQLite数据库存储数据;SQLite是Android所带的一个标准的数据库,它支持SQL语句,它是一个轻量级的嵌入式数据库。(4)使用ContentProvider存储数据;主要用于应用程序之间进行数据交换,从而能够让其他的应用保存或读取此Content Provider的各种数据类型。(5)网络存储数据;通过网络上提供给我们的存储空间来上传(存储)和下载(获取)我们存储在网络空间中的数据信息。4.Android中Activity, Intent, Content Provider, Service各有什么区别。答:Activity: 活动
5、,是最基本的android应用程序组件。一个活动就是一个单独的屏幕,每一个活动都被实现为一个独立的类,并且从活动基类继承而来。Intent: 意图,描述应用想干什么。最重要的部分是动作和动作对应的数据。Content Provider:内容提供器,android应用程序能够将它们的数据保存到文件、SQLite数据库中,甚至是任何有效的设备中。当你想将你的应用数据和其他应用共享时,内容提供器就可以发挥作用了。Service:服务,具有一段较长生命周期且没有用户界面的程序。5.View, surfaceView, GLSurfaceView有什么区别。答:view是最基础的,必须在UI主线程内更新
6、画面,速度较慢。SurfaceView 是view的子类,类似使用双缓机制,在新的线程中更新画面所以刷新界面速度比view快GLSurfaceView 是SurfaceView的子类,opengl 专用的6.Adapter有什么作用?常见的Adapter有哪些?答:Adapter是连接后端数据和前端显示的适配器接口。常见的Adapter有ArrayAdapter, BaseAdapter, CursorAdapter, HeaderViewListAdapter, ListAdapter, ResourceCursorAdapter, SimpleAdapter, SimpleCursorAd
7、apter, SpinnerAdapter, WrapperListAdapter等7.Manifest.xml文件中主要包括哪些信息?答:manifest:根节点,描述了package中所有的内容。uses-permission:请求你的package正常运作所需赋予的安全许可。permission: 声明了安全许可来限制哪些程序能你package中的组件和功能。instrumentation:声明了用来测试此package或其他package指令组件的代码。application:包含package中application级别组件声明的根节点。activity:Activity是用来与用户
8、交互的主要工具。receiver:IntentReceiver能使的application获得数据的改变或者发生的操作,即使它当前不在运行。service:Service是能在后台运行任意时间的组件。provider:ContentProvider是用来管理持久化数据并发布给其他应用程序使用的组件。8.请写一段代码(SAX, DOM, 或者pull )来解析XML文档。答:下面是要解析的XML文件:张三22李四23复制代码定义一个名为Person的javaBean用于存放上面解析出来的xml内容publicclassPerson privateInteger id;privateString
9、name;privateShort age;publicInteger getId() returnid;publicvoidsetId(Integer id) this.id =id;publicString getName() returnname;publicvoidsetName(String name) this.name =name;publicShort getAge() returnage;publicvoidsetAge(Short age) this.age =age;(1)使用SAX读取XML文件;它采用的是事件驱动,并不需要解析完整个文档,速度快并且占用内存少。需要为S
10、AX提供实现ContentHandler接口的类。PersonDefaultHandler.javaAndroid有四大组件:Activity、Service、Broadcast Receiver、Content Provider在这些组件之间的通讯中,主要是由Intent协助完成的。Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。例如,在一个联系
11、人维护的应用中,当我们在一个联系人列表屏幕(假设对应的Activity为listActivity)上,点击某个联系人后,希望能够跳出此联系人的详细信息屏幕(假设对应的Activity为detailActivity)为了实现这个目的,listActivity需要构造一个 Intent,这个Intent用于告诉系统,我们要做“查看”动作,此动作对应的查看对象是“某联系人”,然后调用startActivity (Intent intent),将构造的Intent传入,系统会根据此Intent中的描述,到ManiFest中找到满足此Intent要求的Activity,系统会调用找到的 Activity
12、,即为detailActivity,最终传入Intent,detailActivity则会根据此Intent中的描述,执行相应的操作。android应用开发框架是 Application Framework. 其系统架构由5部分组成,分别是:Linux Kernel、Android Runtime、Libraries、Application Framework、Applications。第二部分将详细介绍这5个部分。下面自底向上分析各层。 Android架构1、Linux KernelAndroid基于Linux 2.6提供核心系统服务,例如:安全、内存管理、进程管理、网络堆栈、驱动模型。Li
13、nux Kernel也作为硬件和软件之间的抽象层,它隐藏具体硬件细节而为上层提供统一的服务。 如果你学过计算机网络知道OSI/RM,就会知道分层的好处就是使用下层提供的服务而为上层提供统一的服务,屏蔽本层及以下层的差异,当本层及以下层发生了变化不会影响到上层。也就是说各层各尽其职,各层提供固定的SAP(Service Access Point),专业点可以说是高内聚、低耦合。 如果你只是做应用开发,就不需要深入了解Linux Kernel层。2、Android RuntimeAndroid包含一个核心库的集合,提供大部分在Java编程语言核心类库中可用的功能。每一个Android应用程序是Da
14、lvik虚拟机中的实例,运行在他们自己的进程中。Dalvik虚拟机设计成,在一个设备可以高效地运行多个虚拟机。Dalvik虚拟机可执行文件格式是.dex,dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。 大多数虚拟机包括JVM都是基于栈的,而Dalvik虚拟机则是基于寄存器的。两种架构各有优劣,一般而言,基于栈的机器需要更多指令,而基于寄存器的机器指令更大。dx 是一套工具,可以将 Java .class 转换成 .dex 格式。一个dex文件通常会有多个.class。由于dex有时必须进行最佳化,会使文件大小增加1-4倍,以ODEX结尾。 Dalvik虚拟机依
15、赖于Linux 内核提供基本功能,如线程和底层内存管理。3、LibrariesAndroid包含一个C/C+库的集合,供Android系统的各个组件使用。这些功能通过Android的应用程序框架(application framework)暴露给开发者。下面列出一些核心库: 系统C库-标准C系统库(libc)的BSD衍生,调整为基于嵌入式Linux设备 媒体库-基于PacketVideo的OpenCORE。这些库支持播放和录制许多流行的音频和视频格式,以及静态图像文件,包括MPEG4、 H.264、 MP3、 AAC、 AMR、JPG、 PNG 界面管理-管理访问显示子系统和无缝组合多个应用程
16、序的二维和三维图形层 LibWebCore-新式的Web浏览器引擎,驱动Android 浏览器和内嵌的web视图 SGL-基本的2D图形引擎 3D库-基于OpenGL ES 1.0 APIs的实现。库使用硬件3D加速或包含高度优化的3D软件光栅 FreeType -位图和矢量字体渲染 SQLite -所有应用程序都可以使用的强大而轻量级的关系数据库引擎4、Application Framework通过提供开放的开发平台,Android使开发者能够编制极其丰富和新颖的应用程序。开发者可以自由地利用设备硬件优势、访问位置信息、运行后台服务、设置闹钟、向状态栏添加通知等等,很多很多。 开发者可以完全
17、使用核心应用程序所使用的框架APIs。应用程序的体系结构旨在简化组件的重用,任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功能(需要服从框架执行的安全限制)。这一机制允许用户替换组件。 所有的应用程序其实是一组服务和系统,包括: 视图(View)-丰富的、可扩展的视图集合,可用于构建一个应用程序。包括包括列表、网格、文本框、按钮,甚至是内嵌的网页浏览器 内容提供者(Content Providers)-使应用程序能访问其他应用程序(如通讯录)的数据,或共享自己的数据 资源管理器(Resource Manager)-提供访问非代码资源,如本地化字符串、图形和布局文件 通知管理器(No
18、tification Manager)-使所有的应用程序能够在状态栏显示自定义警告 活动管理器(Activity Manager)-管理应用程序生命周期,提供通用的导航回退功能5、ApplicationsAndroid装配一个核心应用程序集合,包括电子邮件客户端、SMS程序、日历、地图、浏览器、联系人和其他设置。所有应用程序都是用Java编程语言写的。更加丰富的应用程序有待我们去开发! 从上面我们知道Android的架构是分层的,非常清晰,分工很明确。Android本身是一套软件堆迭(Software Stack),或称为软件迭层架构,迭层主要分成三层:操作系统、中间件、应用程序。从上面我们也
19、看到了开源的力量,一个个熟悉的开源软件在这里贡献了自己的一份力量。1) 如果代码中出现了乱码,这是什么问题造成的,在你常用的开发工具中,你是怎么去解决这个问题的。Java编程语言默认的编码方式是UNICODE,但Java编译器所使用的字符集则是操作系统默认的字符集,中文的Windows是GBK,英文系统则是ISO8859-1。出现乱码的根本原因是由于被操作的中文字符(变量)的编码格式与目标的编码格式不同,所有这些问题都是发生在字符的读入和输出过程中的,在Java程序中最重要的是保证程序入口和出口的汉字信息不失真。解决方法:选择的中文本地化版本;选择合适的编译参数;通过编程的方式实现字符编码的转
20、换代码;定义字符输出集。2) Java的内存回收机制首先要明确几点: 第一:在垃圾回收器回收垃圾之前,我们先来了解一下Java分配对象的方式,Java的堆更像一个传送带,每分配一个新对象,它就往前移动一格。这意味着对象存储空间的分配速度相当快。Java的“堆指针”只是简单地移动到尚未分配的领域。也就是说,分配空间的时候,“堆指针”只管依次往前移动而不管后面的对象是否还要被释放掉。如果可用内存耗尽之前程序就退出就再好不过了,这样的话垃圾回收器压根就不会被激活。但是由于“堆指针”只管依次往前移动,那么你肯定会想,总有一天内存会被耗尽,垃圾回收器就开始释放内存。这里有人肯定会问:怎么判断某个对象该被
21、回收呢?答案就是当堆栈或静态存储区没有对这个对象的引用时,就表示程序(员)对这个对象没有兴趣了,它就应该被回收了。有两种方法来知道这个对象有没有被引用:第一种是遍历堆上的对象找引用;第二种是遍历堆栈或静态存储区的引用找对象。前者的实现叫做“引用计数法”,意思就是当有引用连接至对象时,引用计数加1,当引用离开作用域或被置为null时,引用计数减1,这种方法有个缺陷,如果对象之间存在循环引用,可能会出现“对象应该被回收,但引用计数却不为零”的情况。 第二:Java采用的是后者,在这种方式下,Java虚拟机采用一种“自适应”的垃圾回收技术,如何处理找到的存活对象(也就是说不是垃圾), Java有两种
22、方式: 一种是“停止-复制”:理论上是先暂停程序的运行(所以它不属于后台回收模式),然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的全是垃圾。当对象被复制到新堆上时,它们是一个挨着一个的,所以新堆保持紧凑排列(这也是为什么分配对象的时候“堆指针”只管依次往前移动)。然后就可以按前述方法简单、直接地分配内存了。这将导致大量内存复制行为,内存分配是以较大的“块”为单位的。有了块之后,垃圾回收器就可以不往堆里拷贝对象了,直接就可以往废弃的块里拷贝对象了。 另一种是“标记-清扫”:它的思路同样是从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活的对象。每当它找到一个存活对象,就会给对象一
23、个标 记。这个过程中不会回收任何对象。只有全部标记完成时,没有标记的对象将被释放,不会发生任何复制工作,所以剩下的堆空间是不连续的,然后垃圾回收器 重新整理剩余的对象,使它们是连续排列的。 当垃圾回收器第一次启动时,它执行的是“停止-复制”,因为这个时刻内存有太多的垃圾。然后Java虚拟机会进行监视,如果所有对象都很稳定,垃圾回收器的效率降低的话,就切换到“标记-清扫”方式;同样,Java虚拟机会跟踪“标记-清扫”效果,要是堆空间出现很多碎片,就会切换到“停止-复制”方式。这就是所谓的“自适应”技术。其实仔细想一下,“停止-复制”和“标记-清扫”无非就是:“在大量的垃圾中找干净的东西和在大量干
24、净的东西里找垃圾”。不同的环境用不同的方式,这样做完全是为了提高效率,要知道,无论哪种方式,Java都会先暂停程序的运行,所以,垃圾回收器的效率其实是很低的。3) 计算机组成原理的东西,高位和低位计算的东西4) 宏内核和微内核的区别老一点的操作系统都是宏内核的,也就是说,整个操作系统是一个运行在核心态的单独的a.out文件,这个二进制文件包含进程管理、内存管理、文件系统以及其他。具体实例包括UNIX、MS-DOS、 VMS、MVS、OS/360、MULTICS等。另一种便是微内核,在这种系统中操作系统的大部分都运行在单独的进程,而且多数在内核之外。它们之间通过消息传递来通信。内核的任务是处理消
25、息传递、中断处理、底层的进程管理,以及可能的I/O。这种设计的实例有RC4000、Amoeba、Chorus、Mach,以及还没有发布的Windows/NT。宏内核看上去试图包办一切,而微内核恰恰相反,它的任务只是“处理消息传递、中断处理、底层的进程管理,以及可能的I/O”,而其他事情都交给内核之外单独的进程来完成。宏内核和微内核最大的差别在于,微内核仅在内核中完成如今成调度之类操作系统的最基本的功能,而宏内核则是倾向于将尽可能多的功能放在内核中实现。大家可以看看大牛Tanenbaum和Linus关于微内核和宏内核孰优孰劣的两次争论,很有价值!5) 结合进制间的转换,以及byte的取值范围进行
26、判断代码的输出结果java byte 类型的取值范围是-128127int n1 = 14; /十进制转成十六进制: Integer.toHexString(n1); /十进制转成八进制 Integer.toOctalString(n1); /十进制转成二进制 Integer.toBinaryString(12); /十六进制转成十进制 Integer.valueOf(FFFF,16).toString(); /十六进制转成二进制 Integer.toBinaryString(Integer.valueOf(FFFF,16); /十六进制转成八进制 Integer.toOctalString(
27、Integer.valueOf(FFFF,16); /八进制转成十进制 Integer.valueOf(576,8).toString(); /八进制转成二进制 Integer.toBinaryString(Integer.valueOf(23,8); /八进制转成十六进制 Integer.toHexString(Integer.valueOf(23,8);/二进制转十进制 Integer.valueOf(0101,2).toString(); /二进制转八进制 Integer.toOctalString(Integer.parseInt(0101, 2); /二进制转十六进制Integer.
28、toHexString(Integer.parseInt(0101, 2);6) 至少说出三个Android常用的开发框架ThinkAndroid是一个免费的开源的、简易的、遵循Apache2开源协议发布的Android开发框架,其开发宗旨是简单、快速的进行 Android应用程序的开发,包含Android mvc、简易sqlite orm、ioc模块、封装Android httpclitent的http模块, 具有快速构建文件缓存功能,无需考虑缓存文件的格式,都可以非常轻松的实现缓存,它还基于文件缓存模块实现了图片缓存功能, 在android中加载的图片的时候,对oom的问题,和对加载图片错
29、位的问题都轻易解决。afinal是一个开源的android的orm和ioc应用开发框架,其特点是小巧灵活,代码入侵量少。libGdx是一个跨平台的2D/3D的游戏开发框架,它由Java/C/C+语言编写而成。7) 进程和线程间的区别(好像有这题)从一定意义上讲,进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行。通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。由于线程比进程更小,基本上不拥有系统资源,故对它的调度
30、所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文。多线程主要是为了节约CPU时间,发挥利用,根据具体情况而定。线程的运行中需要使用计算机的内存资源和CPU。线程与进程的区别归纳:a.地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。b.通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信需要进程同步和互斥手段的辅助,以保证数据的一致性。c.调度和切换:线程上下文切换比进程上
31、下文切换要快得多。d.在多线程OS中,进程不是一个可执行的实体。8)写一个计算器,语言不限#include iostream#include stringusing namespace std;/- Stack.h - /定义Stack类const maxsize=20;enum Error_code success, overflow, underflow ;template class Stack public: Stack(); bool empty() const; bool full() const; int size() const; void clear(); Error_cod
32、e top(T &item) const; Error_code pop(); Error_code push(const T &item); private: int count; T entrymaxsize;template Stack:Stack() count=0;template bool Stack:empty () const return count=0;template bool Stack:full () const return count=maxsize;template int Stack:size() const return count;template voi
33、d Stack:clear() count=0;template Error_code Stack:top (T &item) const if (empty() return underflow; item= entrycount-1; return success;template Error_code Stack:pop () if (empty() return underflow; count-; return success;template Error_code Stack:push (const T &item) if (full() return overflow; entr
34、ycount+=item; return success;/-额外函数-bool user_says_yes() int c; bool initial_response = true; do / Loop until an appropriate input is received. if (initial_response) cout (y,n)? flush; else cout Respond with either y or n: flush; do / Ignore white space. c = cin.get(); while (c = n | c = | c = t); i
35、nitial_response = false; while (c != y & c != Y & c != n & c != N); return (c = y | c = Y);/- Main Program -Stack sign;Stack num;int set; / 判断程序中的异常,以便适时退出void process(char c) /计算两个数的 + - * / 运算 int k=0; double a,b; sign.pop(); if (num.top(b)=success) /判断例外 num.pop(); if (num.top(a)=success) num.pop
36、(); k=1; if (k) switch (c) case +: num.push(a+b); break; case -: num.push(a-b); break; case *: num.push(a*b); break; case /: if (b=0) /分母不能为0 set=4; num.push(-1); else num.push(a/b); break; else set=1;num.push(-1); /输入表达式void get_command(string &str) coutn请输入要进行运算的表达式,包括 +,-,*,/,=,(,)和数字,endl 例如: 3+
37、2.5*(6-25/4)-8.32= .endl 注意: 以数字开头,等号结尾,中间括号要匹配.str; /求值 表达式double do_command(const string &str) string s=; double outcome=-1; char c; for (int i=0;stri!=0;i+) if (set!=0) break; /例外 则停止运行 while (1) /分离数据与运算符 if (stri=0 | stri=.) s+=stri; i+; else if(s!=) if (num.push(atof(s.c_str ()=overflow) set=3
38、; s=; break; char ch= stri; switch (ch) /处理运算的优先级,并注意例外抛出 case *: case /: if (sign.top(c)=success) if(c=*|c=/) process(c); if (sign.push(ch)=overflow) set=3; break; case +: case -: while (sign.top(c)=success) if (c!=() process(c); else break; if (sign.push(ch)=overflow) set=3; break; case (: if (sig
39、n.push(ch)=overflow) set=3; break; case ): while (sign.top(c)=success) if (c!=() process(c); else break; sign.pop(); break; case =: while (sign.top(c)=success) if (c!=() process(c); else break; break; default: set=2;break; if (num.size()=1 & sign.size()=0) num.top(outcome); else set=1; if (set=0) co
40、ut运算结果是:nendl; /出错时的错误信息 else outcome=-1; if (set=1) coutn您输入的不匹配,有错误发生。Result lost!endl; if (set=2) coutn您输入了非法字符 , 请重新输入,谢谢合作!endl; if (set=3) coutnStack is full, Lost result!endl; if (set=4) coutn 分母为0,不能进行除法运算,出现溢出, Lost result!endl; return outcome; / 主程序main()int main() do string str,s; set=0;
41、get_command(str); s=str; if( str0=-) str=0+str; /处理表达式中的负号 for (int i=1;stri!=0;i+) if (stri=- & stri-1=() str.insert (i,0); i+; double out= do_command(str); coutsoutendl; /输出结果 num.clear(); /清空栈 sign.clear(); coutn还要计算其它的吗flush; while (user_says_yes(); /允许多次执行运算 return 1;8) 给你一个数组,进行排序,要求所有的奇数在前面,所有的偶数在后面,并且都是从大到小的(大概是这样子的题目)9) 让你写一个程序,能够实现10进制的数字自动转换成16进制的10) 关于排序的题目,好像是写出你会的排序方法,然后写出其中一种你会的代码11) 写两个线程,