面试题 - gmtalang/test GitHub Wiki
-
1.关于ServiceConnection接口的onServiceConnected()方法的触发条件描述正确的是? bindService()方法执行成功同时onBind()方法返回非空IBinder对象
-
2.执行结果: public classMainActivity extends Activity implements OnClickListener
-
{
-
private Button mBtnLogin = (Button) findViewById(R.id.btn_login);
-
private TextView mTextViewUser;
-
@Override
-
protected void onCreate(BundlesavedInstanceState)
-
{
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_main);
-
mTextViewUser = (TextView) findViewById(R.id.textview_user);
-
mBtnLogin.setOnClickListener(this);
-
new Thread()
-
{
-
@Override
-
public void run()
-
{
-
mTextViewUser.setText(10);
-
}
-
}.start();
-
}
-
@Override
-
public void onClick(View v)
-
{
-
mTextViewUser.setText(20);
-
}
-
}
-
3.线程池几种配置参数的理解
-
创建ThreadPoolExecutor可以通过构造方法和Executors的静态方法。
-
构造方法:
-
public ThreadPoolExecutor(int corePoolSize,
-
int maximumPoolSize,
-
long keepAliveTime,
-
TimeUnit unit,
-
BlockingQueue<Runnable> workQueue,
-
ThreadFactory threadFactory,
-
RejectedExecutionHandler handler)
-
corePoolSize,线程池里最小线程数
-
maximumPoolSize,线程池里最大线程数量,超过最大线程时候会使用RejectedExecutionHandler
-
keepAliveTime,unit,线程最大的存活时间
-
workerQueue,缓存异步任务的队列
-
threadFactory,用来构造线程池里的worker线程
-
线程池提交任务流程,以下代码有简化
-
Runnable command
-
if (workerCount < corePoolSize) {
-
new Worker().run(command);
-
workerCount++
-
}
-
if (workerQueue.offer(command)) { //入队
-
// 还没达到maximumPoolSize 创建worker
-
new Worker();
-
workerCount++;
-
} else if (!addWorker(command)) { //还没达到maximumPoolSize,创建worker并运行
-
handler.rejectedException(command)
-
}
-
线程池中线程不足corePoolSize的时候直接创建线程运行command,不然的话提交到队列,其他worker会对这个队列做poll。
-
当workerQueue队列满了的时候,会创建新的worker,如果worker达到上限会调用handler.rejectedException方法。
-
Executors.newCachedThreadPool
-
core是0,max是无限,队列是SynchronousQueue。无限创建线程,线程60S过期被销毁。风险点是线程数不可控。
-
Executors.newFixedThreadPool
-
core是thread数量,max是thread数量,队列是LinkedBlockingQueue。因为LinkedBlockingQueue是无界的,所以max不会起作用。风险点是workerQueue的长度不可控
-
关于ThreadPoolExecutor.DiscardPolicy和ThreadPoolExecutor.CallerRunsPolicy
-
一个是队列慢了就丢弃。一个是队列满了就使用主线程来执行,变成同步调用的方式。主线程就是调用submit方法的线程。
-
我的任务是请求外部HTTP链接,且允许失败,我希望不要影响其他线程。
-
使用线程池的参数:
-
new ThreadPoolExecutor(
-
10, 100, 60, TimeUnit.SECONDS, //限制最大线程,如果是CPU密集型的任务,核心线程就用核数,最大线程就用核数的N倍
-
new ArrayBlockingQueue(1000), //固定大小,防止内存堆积过多
-
new NamedThreadFactory("third_retrieval"), //自己的ThreadFactory
-
new ThreadPoolExecutor.DiscardPolicy()) //当任务对接的时候直接丢弃
-
4.style和theme的区别
-
补充一句:style和theme本质上就是同一个东西,xml格式完全相同,只是我用在activity上我就叫他theme,我用在view上我就叫他style。唯一的区别就是style里头控制的各个属性了,某些属性是只有针对Activity才能生效的(你view有标题栏嘛有状态栏有导航栏吗嘛?但是反过来Activity内部却有一个继承自View的Decorview) 。所以style可以作用在activity上,但是theme却不能反过来作用在view上
-
至于C,如一楼C.C.所说的,出题人所说能不能继承指的是Theme这个类的不可继承,强调的是类为final所以不能继承。而在XML里头使用parent来指明父Theme这种不属于类的继承。 也算是有歧义的题目了,因为不知道“继承”是指类的这种狭义的继承还是后者那种广义的继承。