顯示具有 android 標籤的文章。 顯示所有文章
顯示具有 android 標籤的文章。 顯示所有文章

2019年10月12日 星期六

[面試] 2019 Android Engineer面試考題整理

今年1月剛換一份工作,
每天都是幹勁滿滿的在碰新東西,
直到7月…還是要繼續碰新東西XD
只是面向比較不同。

待在公司的時候可以專注研究跟實作一些特別的架構,
而如果是為了面試,
就必須迅速pick up起來一些市場上正熱的東西,像是MVVM,
在時間足夠的情況下最好也寫一些專案實際操作,
才會了解實務上會遇到的一些狀況以及優缺點等等。

以下整理了一些較常被問到的問題,
不一樣的人去面試會遇到的問題不盡相同,
這跟你待過的公司、做過的東西以及年資都有相關性,
anyway,希望這些題目對在準備面試的你有幫助~

Android考題
  1. service與intent service的不同
  2. startCommand與binding的問題
  3. 不用Rx的話要怎麼處理跨線程問題?
  4. 介紹Async task 
  5. 解釋Thread Handler/Looper的運作方式與關係
  6. 兩個線程溝通方式
  7. 請解釋JAVA記憶體管理機制
  8. ArrayList與LinkedList的不同以及優缺點
  9. MVC/MVP/MVVM:描述三者之間的優劣與分析
  10. 請寫出你在Android常使用的三種設計模式(Design Pattern)
  11. 請描述Android中Touch事件的分發(dispatch)機制
  12. 請試著解釋Handler, MessageQueue, Looper的主要使用場景及三者之間的關聯
  13. 是否有優化app的經驗?如何優化?如何證明優化(是否有做實驗)?
  14. 有使用過include, merge, viewstub嗎?
  15. 使用過哪些第三方工具或framework? 請描述使用場景跟為何選擇該第三方工具?

發現實在是寫不完欸XDDD
都可以寫個100題了,
如果之後還有機會補充我會再加上來~
最後來個面試小心得,
這次面試下來覺得面試流程最舒服的是Yahoo!
面試的team是商城team,
面試官會問有沒有用過abcd....
我自己在面試的時候只要說到"沒用過",
心裏就會開始小緊張,
想說是不是跟他們要找的人條件不吻合。

面試官當下有告訴我,
他們問這樣的問題只是想知道我用過以及熟悉的技術,
再去問那方面的題目,
一定不會有人什麼都會、什麼都清楚,
要我不需要緊張或覺得負面,
真心覺得很謝謝考官能夠讓我屏除緊張、靜下來好好討論~


以上!
希望有幫助到在做面試準備的你,
喜歡文章幫我點一下廣告喔~




2017年10月19日 星期四

[教學] 查詢app的各種資訊




查詢LPDDR3使用量
1.
adb shell dumpsys meminfo <packge name> -d
example:
adb shell dumpsys meminfo com.mickey.app.home
看app summary, Total的部分
2.
adb shell top -s rss -m 15 -d 1
看rss數值


查詢開啟app開啟時間
adb shell am start -W <package name>/<activity>
example:
adb shell am start -W com.mickey.app.home/com.mickey.app.home.HomeActiviy
看Total Time的部分


查詢EMMC使用量
直接看app大小



2016年12月19日 星期一

[教學] open failed: EACCES (Permission denied)

今天下午需要寫一個撥放mp4的test app
結果我無論怎麼改程式都無法撥放!
憤怒!


PS:Android Version :6.0.1


error log:
12-19 16:45:51.146: W/System.err(13135): java.io.FileNotFoundException: /storage/emulated/0/emot_peace.mp4: open failed: EACCES (Permission denied)
12-19 16:45:51.147: W/System.err(13135): at libcore.io.IoBridge.open(IoBridge.java:452)
12-19 16:45:51.147: W/System.err(13135): at java.io.FileInputStream.<init>(FileInputStream.java:76)
12-19 16:45:51.147: W/System.err(13135): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1090)
12-19 16:45:51.147: W/System.err(13135): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1041)
...


permission都有開:
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>


存取檔案的方式也都對:
File dir = Environment.getExternalStorageDirectory().getAbsoluteFile();
        File myFile = new File(dir, "xxx.mp4");
        String path= myFile.toString();
        if(myFile.exists())
            Log.d("Mickey", "path = "+path);


所以究竟怎麼回事呢?

其實不是程式本身的問題
1.開啟設定
2.選擇應用程式 -> 點入你的App ->  點入權限





























3. 把"儲存"的權限打開





我的mp4就可以正常撥了~~~
不經一事不長一智QQ






2016年9月19日 星期一

[教學] "gen already exists but is not a source folder" 排除方法


寫程式總會遇到許多紅字,
今天遇到的紅字是
gen already exists but is not a source folder. Convert to a source folder or rename it.



























這太鬧了,
目錄怎麼變成這樣呢?
看了就想按Delete


好啦其實這小事



1. 在project上按右鍵,選"Properties"





























2. 選 "JAVA Build Path" ,用中文說就是爪哇bu佩斯



































3. 選 "Add Folder",用中文來說就是唉得豐德



































4. 把 "gen"勾起來,(還記得提示裡面是跟你說gen有問題嗎?),
用中文來說就是
把針勾起來.































5. 然後按個Apply -> OK,然後就萬事OK惹!































就說很簡單吧!

小抄版本:
1. 在project上按右鍵,選"Properties"
2. 選 "JAVA Build Path"
3. 選 "Add Folder"
4. 把 "gen"勾起來
5. 然後按個Apply -> OK




好!掰掰!








2016年7月24日 星期日

[教學][android] OpenGL ES 繪製座標軸






















































大家安安~
今天不專業宅妹來做一個簡單的OpenGL ES教學
(一直懶得研究OpenGL ES 2.0聽說極度麻煩

主題簡單而言
就是繪製出xyz軸,並且能夠旋轉畫面.


layout部分就是~~~~什麼都不用

1
2
3
4
5
6
7
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

</RelativeLayout>


然後你的package裡面會有兩個class,
分別是
MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.example.gl_lines_test;
/*
 * References:
 * http://www.developer.com/ws/android/programming/opengl-es-for-android-graphics-programming.html
 * 
 */
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;

public class MainActivity extends Activity {
    private GLSurfaceView mView; 
    private MyRenderer mRenderer; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState); 
          mView = new GLSurfaceView(this); 
          mRenderer = new MyRenderer(this); 
          mView.setRenderer(mRenderer);
          setContentView(mView); 
//        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);
        }

        public boolean onTouchEvent(MotionEvent event) {
          return mRenderer.onTouchEvent(event); 
        }
}

這邊會收TouchEvent並傳給MyRenderer,去處理相關事件.





MyRenderer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package com.example.gl_lines_test;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;
import android.view.MotionEvent;

public class MyRenderer implements Renderer{
    private Context mContext; 
    private FloatBuffer mVertexBuffer = null; 
    private ShortBuffer mTriangleBorderIndicesBuffer = null; 
    private int mNumOfTriangleBorderIndices = 0;   
  
    public float mAngleX = 0.0f; 
    public float mAngleY = 0.0f; 
    public float mAngleZ = 0.0f; 
    private float mPreviousX; 
    private float mPreviousY; 
    private final float TOUCH_SCALE_FACTOR = 0.6f;
    private final float AXIS_SCALE_FACTOR = 1.5f;
    private final int AXIS_WIDTH = 10;
    private final float POINT_WIDTH = 10f;
  
    public MyRenderer(Context context) { 
      mContext = context; 
    } 

    public void onDrawFrame(GL10 gl) { 
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
      gl.glMatrixMode(GL10.GL_MODELVIEW); 
      gl.glLoadIdentity();
  
      gl.glTranslatef(0.0f, 0.0f, -3.0f); 
      gl.glRotatef(mAngleX, 1, 0, 0); 
      gl.glRotatef(mAngleY, 0, 1, 0); 
      gl.glRotatef(mAngleZ, 0, 0, 1); 
      gl.glScalef(AXIS_SCALE_FACTOR, AXIS_SCALE_FACTOR, AXIS_SCALE_FACTOR);
  
      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer); 
  
      gl.glLineWidth(AXIS_WIDTH);

      // Draw x line
      // Set line color to green     
      gl.glColor4f(0.0f, 1.0f, 0.0f, 1.0f); 
      gl.glDrawArrays(GL10.GL_LINES, 0, 2);
      gl.glDrawArrays(GL10.GL_LINES, 9, 2);
      gl.glDrawArrays(GL10.GL_LINES, 11, 2);

      // Draw y line
      // Set line color to red
      gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
      gl.glDrawArrays(GL10.GL_LINES, 2, 2);
      gl.glDrawArrays(GL10.GL_LINES, 13, 2);
      gl.glDrawArrays(GL10.GL_LINES, 15, 2);

      // Draw z lines
      // Set line color to blue
      gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
      gl.glDrawArrays(GL10.GL_LINES, 4, 2);
      gl.glDrawArrays(GL10.GL_LINES, 17, 2);
      gl.glDrawArrays(GL10.GL_LINES, 19, 2);

      gl.glPointSize(POINT_WIDTH);
      gl.glColor4f(1.0f, 0.0f, 1.0f, 1.0f);
      gl.glDrawArrays(GL10.GL_POINTS, 5, 3);
    } 

    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
      gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
      gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 
      gl.glEnable(GL10.GL_DEPTH_TEST); 
  
      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
  
      // Get all the buffers ready
      setAllBuffers();
    } 

    public void onSurfaceChanged(GL10 gl, int width, int height) { 
      gl.glViewport(0, 0, width, height); 
      float aspect = (float)width / height; 
      gl.glMatrixMode(GL10.GL_PROJECTION); 
      gl.glLoadIdentity();
      gl.glFrustumf(-aspect, aspect, -1.0f, 1.0f, 1.0f, 10.0f); 
    } 
  
    private void setAllBuffers(){
          // Set vertex buffer
          float vertexlist[] = { 
           -1.0f, 0.0f, 0.0f,   //0 X-axis
            1.0f, 0.0f, 0.0f,   //1 X-axis
            0.0f, 1.0f, 0.0f,   //2 Y-axis
            0.0f,-1.0f, 0.0f,   //3 Y-axis
            0.0f, 0.0f, 1.0f,   //4 Z-axis
            0.0f, 0.0f,-1.0f,   //5 Z-axis
            -0.5f , -0.5f, 0.0f ,   //6 point 1
            0.5f, -0.5f, 0.0f ,    //7 point 2
            0.0f , 0.5f, 0.0f ,      //8 point 3
            0.9f, 0.1f, 0.0f,    //9  X-axis
            1.0f, 0.0f, 0.0f,    //10 X-axis
            0.9f,-0.1f, 0.0f,    //11 X-axis
            1.0f, 0.0f, 0.0f,    //12 X-axis
            -0.1f, 0.9f, 0.0f,   //13 Y-axis
            0.0f, 1.0f, 0.0f,    //14 Y-axis
            0.1f, 0.9f, 0.0f,     //15 Y-axis
            0.0f, 1.0f, 0.0f,    //16 Y-axis
            0.1f, 0.0f, 0.9f,    //17 Z-axis
            0.0f, 0.0f, 1.0f,    //18 Z-axis
            -0.1f,0.0f, 0.9f,    //19 Z-axis
            0.0f, 0.0f, 1.0f,    //20 Z-axis
          };

          ByteBuffer vbb = ByteBuffer.allocateDirect(vertexlist.length * 4); 
          vbb.order(ByteOrder.nativeOrder());
          mVertexBuffer = vbb.asFloatBuffer();
          mVertexBuffer.put(vertexlist); 
          mVertexBuffer.position(0); 
      } 

    public boolean onTouchEvent(MotionEvent e) { 
      float x = e.getX();
      float y = e.getY();
      switch (e.getAction()) { 
       case MotionEvent.ACTION_MOVE: 
          float dx = x - mPreviousX; 
          float dy = y - mPreviousY; 
          mAngleY = (mAngleY + (int)(dx * TOUCH_SCALE_FACTOR) + 360) % 360; 
          mAngleX = (mAngleX + (int)(dy * TOUCH_SCALE_FACTOR) + 360) % 360; 
          break; 
      } 
      mPreviousX = x; 
      mPreviousY = y; 
      return true; 
    } 
}


好,因為我不知道怎麼把程式碼分開貼,
所以大概挑幾個部分講 XD

1. import有兩行被我標了黃色
那是一個容易import錯library的地方,
如果你的code一直有問題,
可能可以看看是不是選錯library.


2. 為了改code跟視覺上調整方便,
建議座標範圍都正規劃,再用factor、scale去做調整.


3.  拿繪製 x軸來講
      // Draw x line
      // Set line color to green     
      gl.glColor4f(0.0f, 1.0f, 0.0f, 1.0f); 
      gl.glDrawArrays(GL10.GL_LINES, 0, 2);
      gl.glDrawArrays(GL10.GL_LINES, 9, 2);
      gl.glDrawArrays(GL10.GL_LINES, 11, 2);

glColor4f是指定顏色,有興趣可以看一下android developers的介紹
gl.glDrawArrays(GL10.GL_LINES, 0, 2);
第一個欄位是指定要畫的型態是什麼,可以指定點啊、線blablabla,
然後 "0, 2"是指:
vertexlist[0]開始數2個element進行繪製,
換言之這邊會繪製vertexlist[0]與vertexlist[1].


規則大概就是這樣~
我想應該還有些其他的繪製方式,
但如果只是要畫三軸的話這樣很快!
下次來寫畫球好了.
掰掰~~~




Reference: OpenGL ES for Android Graphics Programming