52. Linux中跨进程通信的几种方式 。 linux编程全部是基于文件管理的。 # 管道( pipe ):管道也是一个文件,一个进程负责读一个进程负责写,管道是一种半双工(2边可以通信但是不能是同时的比如对讲机)的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程(一个进程new了另一个进程)关系或者兄弟进程(一个进程new了2个进程,这2个进程就是兄弟进程)。 # 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。 # 信号量( semophore ) : 信号量是一个计数器,多线程中使用,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。 # 消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。 # 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。 # 共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。 # 套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。 53. 谈谈对Android NDK的理解。用在windows系统, native develop kit 只是一个交叉编译的工具 .so,主要用于编译jni代码,java效率不如C++的时候会去用jni ,C++编译完后都是二进制代码,手机分为arm架构和x86架构,2中架构的CPU的指令集是不一样的,在x86也就是windows上编译出来的代码不能运行在arm架构上,因为指令集不一样,所以就要转换这就要交叉编译,在windows平台下面需要编译出来一套能适用在arm架构运行的二进制文件。 1.什么时候用ndk, 实时性要求高,游戏,图形渲染, opencv (人脸识别) , ffmpeg , rmvb mp5 avi 高清解码. ffmpeg, opencore. 2.为什么用ndk,ndk的优点 ,缺点 , 效率高但是出现bug很难定位。 我们项目中那些地方用到了ndk, 54. 谈谈Android的优点和不足之处。 1、开放性,开源 ophone 阿里云( 完全兼容android) 2、挣脱运营商束缚 3、丰富的硬件选择 mtk做硬件的 ,高通做手机硬件的,android 4、不受任何限制的开发商 5、无缝结合的Google应用 缺点也有5处: 1、安全问题、隐私问题 :源码可以看见, 2、卖手机的不是最大运营商 3、运营商对Android手机仍然有影响,手机屏幕分辨率不一样。 4、山寨化严重 5、过分依赖开发商,缺乏标准配置 55. Android系统中GC什么情况下会出现内存泄露呢? 视频编解码/内存泄露 检测内存泄露 工具 mat C:\Users\lenovo\Desktop\prof>hprof-conv com.example.testmat.hprof convert-com.ex ample.testmat.hprof 导致内存泄漏主要的原因是,先前申请了内存空间而忘记了释放(已经没有用了但是没有断开引用就是泄漏,内存溢出就是内存不足)。如果程序中存在对无用对象的引用,那么这些对象就会驻留内存,消耗内存,因为无法让垃圾回收器GC验证这些对象是否不再需要。如果存在对象的引用,这个对象就被定义为"有效的活动",同时不会被释放。要确定对象所占内存将被回收,我们就要务必确认该对象不再会被使用。典型的做法就是把对象数据成员设为null或者从集合中移除该对象。但当局部变量不需要时,不需明显的设为null,因为一个方法执行完毕时,这些引用会自动被清理。 Java带垃圾回收的机制,为什么还会内存泄露呢? Vector v = new Vector(10); for (int i = 1; i < 100; i++) { Object o = new Object(); v.add(o); o = null; }//此时,所有的Object对象都没有被释放,因为变量v引用这些对象。 Java 内存泄露的根本原因就是 保存了不可能再被访问的变量类型的引用 56. Android UI中的View如何刷新。 在主线程中 拿到view调用Invalide()方法,查看画画板里面更新imageview的方法 在子线程里面可以通过postInvalide()方法; View view; view.invalidate();//主线程,让view执行onDraw()方法 view.postInvalidate();//子线程,让view执行onLayout()方法 57.简单描述下Android 数字签名。 签名不一样则不会覆盖老软件,如果新软件包名和旧的一样但是签名不一样则新的软件也不会安装。 Android 数字签名 在Android系统中,所有安装到系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系 Android系统要求每一个安装进系统的应用程序都是经过数字证书签名的,数字证书的私钥则保存在程序开发者的手中。Android将数字证书用来标识应用程序的作者和在应用程序之间建立信任关系,不是用来决定最终用户可以安装哪些应用程序。 这个数字证书并不需要权威的数字证书签名机构认证(CA),它只是用来让应用程序包自我认证的。 同一个开发者的多个程序尽可能使用同一个数字证书,这可以带来以下好处。 (1)有利于程序升级,当新版程序和旧版程序的数字证书相同时,Android系统才会认为这两个程序是同一个程序的不同版本。如果新版程序和旧版程序的数字证书不相同,则Android系统认为他们是不同的程序,并产生冲突,会要求新程序更改包名。 (2)有利于程序的模块化设计和开发。Android系统允许拥有同一个数字签名的程序运行在一个进程中,Android程序会将他们视为同一个程序。所以开发者可以将自己的程序分模块开发,而用户只需要在需要的时候下载适当的模块。 在签名时,需要考虑数字证书的有效期: (1)数字证书的有效期要包含程序的预计生命周期,一旦数字证书失效,持有改数字证书的程序将不能正常升级。 (2)如果多个程序使用同一个数字证书,则该数字证书的有效期要包含所有程序的预计生命周期。 (3)Android Market强制要求所有应用程序数字证书的有效期要持续到2033年10月22日以后。 Android数字证书包含以下几个要点: (1)所有的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序 (2)Android程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证 (3)如果要正式发布一个Android ,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布。 (4)数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能。 58. 什么是ANR 如何避免它? 在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框。用户可以选择让程序继续运行,但是,他们在使用你的应用程序时,并不希望每次都要处理这个对话框。因此,在程序里对响应性能的设计很重要,这样,系统不会显示ANR给用户。 Activity 5秒 broadcast10秒 耗时的操作 worker thread里面完成, handler message…AsynTask , intentservice.等… 59. android中的动画有哪几类,它们的特点和区别是什么? 两种,一种是Tween移动,缩放,旋转,动画、还有一种是Frame跟视频一样动画。 Tween动画,这种实现方式可以使视图组件移动、放大、缩小以及产生透明度的变化; 可以通过布局文件,可以通过代码 1、 控制View的动画 a) alpha(AlphaAnimation) 渐变透明 b) scale(ScaleAnimation) 渐变尺寸伸缩 c) translate(TranslateAnimation) 画面转换、位置移动 d) rotate(RotateAnimation) 画面转移,旋转动画 2、 控制一个Layout里面子View的动画效果 a) layoutAnimation(LayoutAnimationController) b) gridAnimation(GridLayoutAnimationController) 另一种Frame动画,传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影。 属性动画 ObjectAnimator :改变view位置 62. 说说mvc模式的原理,它在android中的运用。 MVC英文即Model-View-Controller,即把一个应用的输入、处理、输出流程按照Model、View、Controller的方式进行分离,这样一个应用被分成三个层——模型层、视图层、控制层。 Android中界面部分也采用了当前比较流行的MVC框架,在Android中M就是应用程序中二进制的数据,V就是用户的界面。Android的界面直接采用XML文件保存的,界面开发变的很方便。在Android中C也是很简单的,一个Activity可以有多个界面,只需要将视图的ID传递到setContentView(),就指定了以哪个视图模型显示数据。 在Android SDK中的数据绑定,也都是采用了与MVC框架类似的方法来显示数据。在控制层上将数据按照视图模型的要求(也就是Android SDK中的Adapter)封装就可以直接在视图模型上显示了,从而实现了数据绑定。比如显示Cursor中所有数据的ListActivity,其视图层就是一个ListView,将数据封装为ListAdapter,并传递给ListView,数据就在ListView中显示。 63. 通过点击一个网页上的url 就可以完成程序的自动安装,描述下原理 Day11 AddJavascriptInterface new Object{ callphone(); installapk(); } 64,Service和Activity在同一个线程吗 默认情况同一线程 main主线程 ui线程 65,java中的soft reference是个什么东西 StrongReference 是 Java 的默认引用实现, 它会尽可能长时间的存活于 JVM 内, 当没有任何对象指向它时 GC 执行后将会被回收 SoftReference 会尽可能长的保留引用直到 JVM 内存不足时才会被回收(虚拟机保证), 这一特性使得 SoftReference 非常适合缓存 应用详细见客户端图片的缓存 66,udp连接和TCP的不同之处 tcp/滑动窗口协议. 拥塞控制. 面向连接 流 udp 不关心数据是否达到,是否阻塞 面向无连接 画面优先. tcp 流畅优先 udp 67, android开发中怎么去调试bug 逻辑错误 1.断点 debug 2. logcat , traceview 界面布局,显示 hierarchyviewer.bat 68.service里面可以弹土司么 可以 69.写10个简单的linux命令 cat ls ps psw wc mv rm cd ping tracert find grep tail vi gcc make ifconfig startup dhcp 70 JNI调用常用的两个参数 JNIEnv *env, jobject javaThis 71. 书写出android工程的目录结构 src android. jar asset res gen manifest 72. ddms 和traceview的区别. daivilk debug manager system 1.在应用的主activity的onCreate方法中加入Debug.startMethodTracing("要生成的traceview文件的名字"); 2.同样在主activity的onStop方法中加入Debug.stopMethodTracing(); 3.同时要在AndroidManifest.xml文件中配置权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> 3.重新编译,安装,启动服务,测试完成取对应的traceview文件(adb pull /sdcard/xxxx.trace)。 4.直接在命令行输入traceview xxxxtrace,弹出traceview窗口,分析对应的应用即可。 traceview 分析程序执行时间和效率 KPI : key performance information : 关键性能指标: splash界面不能超过5秒 从splash 界面加载mainactivity 不能超过0.7秒 对于Android 1.5及以下的版本:不支持。 对于Android 1.5以上2.1下(含2.1)的版本:受限支持。trace文件只能生成到SD卡,且必须在程序中加入代码。 对于Android 2.2上(含2.2)的版本:全支持。可以不用SD卡,不用在程序中加代码,直接自己用DDMS就可以进程Traceview。 73. 利用mvc的模式重构代码 1) 重构前的代码Bmi.java: package com.demo.android.bmi; import java.text.DecimalFormat; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class Bmi extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Listen for button clicks Button button = (Button) findViewById(R.id.submit); button.setOnClickListener(calcBMI); } private OnClickListener calcBMI = new OnClickListener() { @Override public void onClick(View v) { DecimalFormat nf = new DecimalFormat("0.00"); EditText fieldheight = (EditText) findViewById(R.id.height); EditText fieldweight = (EditText) findViewById(R.id.weight); double height = Double.parseDouble(fieldheight.getText().toString()) / 100; double weight = Double.parseDouble(fieldweight.getText().toString()); double BMI = weight / (height * height); TextView result = (TextView) findViewById(R.id.result); result.setText("Your BMI is " + nf.format(BMI)); // Give health advice TextView fieldsuggest = (TextView) findViewById(R.id.suggest); if (BMI > 25) { fieldsuggest.setText(R.string.advice_heavy); } else if (BMI < 20) { fieldsuggest.setText(R.string.advice_light); } else { fieldsuggest.setText(R.string.advice_average); } } }; } Step1:抽取所有界面元件的声明和定义,整合到单独一个函数findViews()中; // 声明 view private Button button_calc; private EditText field_height; private EditText field_weight; private TextView view_result; private TextView view_suggest; // 定义 private void findViews() { button_calc = (Button) findViewById(R.id.submit); field_height = (EditText) findViewById(R.id.height); field_weight = (EditText) findViewById(R.id.weight); view_result = (TextView) findViewById(R.id.result); view_suggest = (TextView) findViewById(R.id.suggest); } 此部分即是MVC中的V:View视图。 Step2:抽取程序的逻辑(即界面元件的处理逻辑),整合到函数setListensers()中; //Listen for button clicks private void setListensers() { button_calc.setOnClickListener(calcBMI); } 此部分即是MVC中的C:Controller控制器。 接着,onCreate()就显得非常简洁、明了了: public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); findViews(); setListensers(); } Step3:修改按钮监听器calcBMI中相应的部分(主要是变量已经在视图部分定义了); private OnClickListener calcBMI = new OnClickListener() { @Override public void onClick(View v) { DecimalFormat nf = new DecimalFormat("0.00"); double height = Double.parseDouble(field_height.getText().toString()) / 100; double weight = Double.parseDouble(field_weight.getText().toString()); double BMI = weight / (height * height); // Present result view_result.setText("Your BMI is " + nf.format(BMI)); // Give health advice if (BMI > 25) { view_suggest.setText(R.string.advice_heavy); } else if (BMI < 20) { view_suggest.setText(R.string.advice_light); } else { view_suggest.setText(R.string.advice_average); } } }; 总之,此重构的目的无非是使程序的脉络更加清晰,即让人一眼望去,就能很容易地分辨出界面(View)应该写在哪里,程序逻辑(Controller)应该写在哪里,最终使维护和扩展代码变得更加容易! 其实,重构很简单,通读代码,感觉哪边不太爽,就改那边吧!(我目前的感受) 一个良好的代码应该是能让人感到舒服的! 2) 重构后的代码Bmi.java: package com.demo.android.bmi; import java.text.DecimalFormat; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class Bmi extends Activity { private Button button_calc; private EditText field_height; private EditText field_weight; private TextView view_result; private TextView view_suggest; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); findViews(); setListensers(); } // 定义 private void findViews() { button_calc = (Button) findViewById(R.id.submit); field_height = (EditText) findViewById(R.id.height); field_weight = (EditText) findViewById(R.id.weight); view_result = (TextView) findViewById(R.id.result); view_suggest = (TextView) findViewById(R.id.suggest); } // Listen for button clicks private void setListeners() { calcbutton.setOnClickListener(calcBMI); } private Button.OnClickListener calcBMI = new Button.OnClickListener() { public void onClick(View v) { DecimalFormat nf = new DecimalFormat("0.0"); double height = Double.parseDouble(field_height.getText().toString()) / 100; double weight = Double.parseDouble(field_weight.getText().toString()); double BMI = weight / (height * height); // Present result view_result.setText(getText(R.string.bmi_result) + nf.format(BMI)); // Give health advice if (BMI > 25) { view_suggest.setText(R.string.advice_heavy); } else if (BMI < 20) { view_suggest.setText(R.string.advice_light); } else { view_suggest.setText(R.string.advice_average); } } }; }
时间: 2024-10-28 09:50:03