面试题 - 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这种不属于类的继承。 也算是有歧义的题目了,因为不知道“继承”是指类的这种狭义的继承还是后者那种广义的继承。

⚠️ **GitHub.com Fallback** ⚠️