题目:
考的知识点有:概率、堆排序、进制转换、c++初始化、os的读写锁(并发,排他)、折半查找,os系统调用(用户态内核态切换)
84 *148 =B6A8成立,采用的是多少进制 15,11,12,14,16
概率、堆排序、进制转换、c++初始化、os的读写锁(并发,排他)、折半查找,os系统调用(用户态内核态切换)
大题考的有:
大题考的有:
1.闪退是客户端程序在运行时遭遇无法处理的异常或错误时而退出应用程序的表现,请从crASH发生的原因分类与解决方法,在初夏crash后如何捕捉并分析异常这2个问题给出自己的解决方案
crash 有两种, 一种是 java 的Exception ,另一种是 C/C++ 代码的 Crash
java Exception 又有运行时异常(除零,空指针等) 和 Throw的异常
对于java异常通过try-catch-finally 块捕捉处理,对于上线产品未发现的异常可采用类似bugly这类bug监控插件捕捉
可以注册统一的crash 捕获 回调函数
setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler);用来捕捉未处理的异常
Thread.UncaughtExceptionHandler oldHandler = Thread.getDefaultUncaughtExceptionHandler();用来获取已经设置的 默认异常处理回调
还有就是 native 代码的 crash ,这种异常 目前 bugly也支持捕捉。
java Exception 又有运行时异常(除零,空指针等) 和 Throw的异常
对于java异常通过try-catch-finally 块捕捉处理,对于上线产品未发现的异常可采用类似bugly这类bug监控插件捕捉
可以注册统一的crash 捕获 回调函数
setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler);用来捕捉未处理的异常
Thread.UncaughtExceptionHandler oldHandler = Thread.getDefaultUncaughtExceptionHandler();用来获取已经设置的 默认异常处理回调
还有就是 native 代码的 crash ,这种异常 目前 bugly也支持捕捉。
要求对外提供以下接口:可指定cache大小;可指定window窗口;提供get/put/remove数据访问方法;提供缓存命中率hitrate数据访问方法
LRU是最近最少使用页面置换算法(Least Recently Used),也就是首先淘汰最长时间未被使用的页面!
LFU是最近最不常用页面置换算法(Least Frequently Used),也就是淘汰一定时期内被访问次数最少的页!
package com.souche.fengche;
import android.text.TextUtils;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* @author esperanza
* @date 8/23/15.
*/
public class LFU {
List<ViewItem> mViewItems;
int mSize = 5;
public LFU(int size) throws Exception {
if (size < 1) {
throw new Exception("wrong size");
}
mSize = size;
mViewItems = new ArrayList<ViewItem>(mSize);
}
public View get(String tag) {
for (int i = 0; i < mViewItems.size(); i++) {
ViewItem item = mViewItems.get(i);
if (TextUtils.equals(item.tag, tag)) {
hit(i);
return item.v;
}
}
return null;
}
public void put(View v, String tag) {
if (v == null || tag == null) {
throw new NullPointerException("View or tag can not be null");
}
//已存在则不作处理
for (int i = 0; i < mViewItems.size(); i++) {
if (TextUtils.equals(mViewItems.get(i).tag, tag)) {
return;
}
}
ViewItem item = new ViewItem();
item.v = v;
item.tag = tag;
item.hit = 0;
item.allhit = 0;
//如果达到cache 上限,删除最下面的元素,如果没有达到则直接增加
if (mViewItems.size() < mSize) {
mViewItems.add(item);
} else {
mViewItems.remove(mViewItems.size() - 1);
mViewItems.add(item);
}
}
public float getHitRate(String tag) {
for (int i = 0; i < mViewItems.size(); i++) {
if (TextUtils.equals(mViewItems.get(i).tag, tag)) {
if (mViewItems.get(i).hit == 0) {
return 0;
} else {
return mViewItems.get(i).hit / mViewItems.get(i).allhit;
}
}
}
return 0;
}
public void remove(String tag) {
for (int i = 0; i < mViewItems.size(); i++) {
if (TextUtils.equals(mViewItems.get(i).tag, tag)) {
mViewItems.remove(i);
}
}
}
private void hit(int pos) {
mViewItems.get(pos).hit += 2;
mViewItems.get(pos).allhit++;
//没个计数减去1
for (int i = 0; i < mViewItems.size(); i++) {
if (mViewItems.get(i).hit != 0) {
mViewItems.get(i).hit--;
}
}
//前移计数增加的
for (int i = mViewItems.size() - 1; i > 0; i--) {
if (mViewItems.get(i).hit > mViewItems.get(i - 1).hit) {
swap(mViewItems, i, i - 1);
}
}
}
private void swap(List<ViewItem> viewItems, int p, int q) {
ViewItem tmp = viewItems.get(p);
viewItems.set(p, viewItems.get(q));
viewItems.set(q, tmp);
}
private class ViewItem {
String tag;
public View v;
public int hit;
public int allhit;
}
}
import android.text.TextUtils;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* @author esperanza
* @date 8/23/15.
*/
public class LFU {
List<ViewItem> mViewItems;
int mSize = 5;
public LFU(int size) throws Exception {
if (size < 1) {
throw new Exception("wrong size");
}
mSize = size;
mViewItems = new ArrayList<ViewItem>(mSize);
}
public View get(String tag) {
for (int i = 0; i < mViewItems.size(); i++) {
ViewItem item = mViewItems.get(i);
if (TextUtils.equals(item.tag, tag)) {
hit(i);
return item.v;
}
}
return null;
}
public void put(View v, String tag) {
if (v == null || tag == null) {
throw new NullPointerException("View or tag can not be null");
}
//已存在则不作处理
for (int i = 0; i < mViewItems.size(); i++) {
if (TextUtils.equals(mViewItems.get(i).tag, tag)) {
return;
}
}
ViewItem item = new ViewItem();
item.v = v;
item.tag = tag;
item.hit = 0;
item.allhit = 0;
//如果达到cache 上限,删除最下面的元素,如果没有达到则直接增加
if (mViewItems.size() < mSize) {
mViewItems.add(item);
} else {
mViewItems.remove(mViewItems.size() - 1);
mViewItems.add(item);
}
}
public float getHitRate(String tag) {
for (int i = 0; i < mViewItems.size(); i++) {
if (TextUtils.equals(mViewItems.get(i).tag, tag)) {
if (mViewItems.get(i).hit == 0) {
return 0;
} else {
return mViewItems.get(i).hit / mViewItems.get(i).allhit;
}
}
}
return 0;
}
public void remove(String tag) {
for (int i = 0; i < mViewItems.size(); i++) {
if (TextUtils.equals(mViewItems.get(i).tag, tag)) {
mViewItems.remove(i);
}
}
}
private void hit(int pos) {
mViewItems.get(pos).hit += 2;
mViewItems.get(pos).allhit++;
//没个计数减去1
for (int i = 0; i < mViewItems.size(); i++) {
if (mViewItems.get(i).hit != 0) {
mViewItems.get(i).hit--;
}
}
//前移计数增加的
for (int i = mViewItems.size() - 1; i > 0; i--) {
if (mViewItems.get(i).hit > mViewItems.get(i - 1).hit) {
swap(mViewItems, i, i - 1);
}
}
}
private void swap(List<ViewItem> viewItems, int p, int q) {
ViewItem tmp = viewItems.get(p);
viewItems.set(p, viewItems.get(q));
viewItems.set(q, tmp);
}
private class ViewItem {
String tag;
public View v;
public int hit;
public int allhit;
}
}
3.给出不依赖发布下载更新方式而完成用户交互界面变更的解决方案
插件apk 开发方式
不过这个目前还是研发阶段,淘宝,腾讯都有自己的 动态加载技术。 目前有个商业化的叫做 apkPlug ,不过不是很成熟。
主要原理是通过 dexClassLoader 动态加载类,但其中还要设计 资源文件访问,生命周期等等一系列问题。
还有一个技术,是同花顺所使用的自己的框架,采用的整个 app 只有 一个 Activity 的技术,使用View 替换的方式达到页面切换。 然后自己管理生命周期,自己管理 Stack
这种方式如果结合 apk动态加载, 可能会屏蔽不少地方的问题。但随之而来的是 或许会在开发商造成一定的难度
不过这个目前还是研发阶段,淘宝,腾讯都有自己的 动态加载技术。 目前有个商业化的叫做 apkPlug ,不过不是很成熟。
主要原理是通过 dexClassLoader 动态加载类,但其中还要设计 资源文件访问,生命周期等等一系列问题。
还有一个技术,是同花顺所使用的自己的框架,采用的整个 app 只有 一个 Activity 的技术,使用View 替换的方式达到页面切换。 然后自己管理生命周期,自己管理 Stack
这种方式如果结合 apk动态加载, 可能会屏蔽不少地方的问题。但随之而来的是 或许会在开发商造成一定的难度