Senior Android interviewer: 75% of developers, the interview will be hung in these 10 performance optimization high-level interview questions

1. Have you done any research on the startup of the app? Have you done any related startup optimization?

programmer:

I studied the startup principle of Application when doing hot repair. Some startup optimizations have also been done in the project.

Interviewer:

Oh, have you studied hot repair before? (At this time, it is possible to ask about the principle of hot repair in depth, here we will not discuss the principle of hot repair) So what optimizations have been made to the startup?

programmer:

  • I found that when the program is cold-started, there will be a white screen flashing for about 1s, and the lower version is a black screen. During this period, I read the system theme source code and found that the system AppTheme has set one windowBackground, which infers that this attribute is caused. ghosts, I started by setting windowIsTranslucenttransparent property, found that although there is no black and white, but the middle is still a short invisible, the user experience is not good. Finally, I have observed most of the Android software available in the market at the time of a cold start, there will be Splashadvertising pages, while a countdown timer to increase, and finally taken to the login page or the home page. I did this in the end, because the advantage of this is that the user can first have a basic understanding of the app based on the advertisement, and it is also reserved for us to make some preparations for plug-ins and some necessary or time-consuming initialization during the countdown. .

Ps: This will make the interviewer feel that you are a user

  • By reading the source code of Application startup, when we click on the desktop icon to enter our software application, AMS will send a fork child process message to Zygote through the Socket. When the Zygote fork child process is completed, the ActivityThread##main function will be started by reflection , Finally, AMS tells ActivityThread##H through aidl to reflectively start the creation of Application instances, and execute them in sequence attachBaseContextand the onCreatelife cycle. This shows that we cannot do the main thread time-consuming operations in these two life cycles.

Ps: This will make the interviewer feel that you have studied the startup process of the App application more deeply, and you have actually read the underlying source code instead of memorizing the answer.

If you know it attachBaseContext, onCreatestart it first in the application, then we can use performance testing tools such as TreceView to detect the time-consuming and time-consuming specific functions, and then make specific optimizations.

Ps: 1. The interviewer here will feel that you have a good understanding of startup optimization and have a certain amount of startup optimization experience.

        2. At the fifth point, the interviewer will feel that you pay more attention to the dynamics of the circle, find a good solution, and can use it in your own project. This is a plus!

  1. The code that the project does not need in time is loaded asynchronously.

  2. Lazy loading will be done for some initializations that are not highly used.

  3. Some time-consuming tasks will be handled by opening an IntentService.

  4. It also rearranges the class files through redex, arranges the files needed during the startup phase together in the APK file, uses the pagecache mechanism of the Linux file system as much as possible, uses the least number of disk IOs, and reads as many startups as possible The files needed in the stage reduce the IO overhead, so as to achieve the purpose of improving the startup performance.

  5. Published by vibrato article in its low version 5.0 can do MultiDexto optimize, when you first start, and loaded directly OPT has not been optimized for the original DEX, before making APP can start properly. Then start a separate process in the background to slowly complete the OPT work of the DEX, and try to avoid affecting the normal use of the foreground APP.

  • After completion of Application start, AMS will identify foreground stack of Activity to be started, the last and AIDL notice ActivityThread # H to be instantiated and executed in sequence through the life cycle of Activity onCreate, onStart, onRemusefunction, this due to the life cycle if the call onCreate the setContentViewfunction, the bottom will by XML2View then this is definitely a time-consuming process. Therefore, it is necessary to streamline the XML layout code, and use ViewStub,, includeand mergetags to optimize the layout as much as possible . Followed by a statement cycle onResume JNI requests received Vsync (vertical synchronization signal refresh) request, if received after 16ms refresh message, it will be of DecorView onMeasure->onLayout->onDrawdrawing. Finally, the Activity's root layout DecorView is added to Window and displayed on SurfaceFlinger. Therefore, in addition to streamlining the XML layout in this step, the measurement, layout, and drawing functions of the custom View must not be time-consuming and cause GC operations. Finally, can also TreaceViewbe detected three lifecycle tool takes time to further optimize the limit.

This step gives the interviewer the feeling that you have in-depth research on the startup of the entire Activity and the drawing of the View and the refresh mechanism. At this moment, you must have left a good impression on the interviewer, indicating that you usually compare these source code levels. Extensive and thorough.

to sum up:

Finally, based on the above optimization, I reduced the startup time by 50%.

Interviewer:

Well, the research is quite deep, and the source code is usually a lot.

programmer:

At this point, I know this level is over!

2.Have you done any related memory optimization?

programmer:

I have done it before, and there are still a lot of memory optimizations in the current project. How about I first talk about the benefits of optimizing memory? We cannot optimize blindly!

Sometimes you must take the initiative to lead the interview in a field you are familiar with.

Interviewer:

can.

Ps: Most interviewers here will agree to your request unless they meet someone who pretends to be B.

programmer:

benefit:

  1. Reducing OOM can improve the stability of the program.

  2. Reduce lag and improve application fluency.

  3. Reduce memory usage and improve application background viability.

  4. Reduce program exceptions, reduce application crash rate, and improve stability.

So based on these four points, my program has been optimized as follows:

  • 1. Reduce OOM

    In the application development stage, I prefer to use LeakCanary, a performance detection tool. The advantage is that it can tell me in real time which class has found a memory leak (if you understand the principle of LeakCanary, you can talk about how it is detected) .

    And we need to understand why the application sends OOM, and how to avoid it?

    The scenario where OOM occurs is when 1M of memory space is requested, if you want to store 2M of data into the memory space, then OOM will occur at this time.

    In the application, we must not only avoid scenarios that directly cause OOM, but also avoid scenarios that indirectly cause OOM. Indirectly, it is to avoid memory leak scenarios.

    The memory leak scenario is that when the object is no longer used, the application performs the final life cycle completely, but for some reasons, although the object is no longer used, it still exists in memory and the GC will not reclaim it. It means that a memory leak has occurred. (Here can introduce the GC recycling mechanism, recycling algorithm, and the knowledge points should be expanded as far as possible without departing from this question)

    Finally, let's talk about the scenarios to avoid memory leaks in actual development:

    1. Resource object is not closed: Cursor, File

    2. Registered object is not destroyed: broadcast, callback monitoring

    3. Static variables of the class hold large data objects

    4. Static instance of non-static inner class

    5. Handler temporary memory leak: use static + weak reference, exit and destroy

    6. Memory leak caused by uncleaned objects in the container

    7. WebView: use a separate process

    In fact, these are the basics, just write them down. Remember too much, you will have an impression in actual development.

  • 2. Reduce lag

    How to reduce the lag? Then we can discuss the root cause of the lag from two principles. The first is the drawing principle and the other is the refresh principle.

  • Drawing principle:

  • Refresh principle:

    View's requestLayout and ViewRootImpl##setView will eventually call ViewRootImpl's requestLayout method, and then submit a drawing task to Choreographer through the scheduleTraversals method, and then request the vsync vertical synchronization signal from the bottom layer through DisplayEventReceiver. When the vsync signal comes, it will call back through JNI Back, post an asynchronous task to the message queue through the Handler, and finally ViewRootImpl performs the drawing task, and finally calls the performTraversals method to complete the drawing.

    The detailed process can refer to the following flowchart:

The root cause of lag:

From the perspective of refresh principle, the basic principle of lag is that there are two places that will cause frame drop:

One is that the main thread has other time-consuming operations, resulting in no chance to call doFrame within 16 milliseconds after the vsync signal is sent;

Another is that the current doFrame method takes too long to draw, and the frame is not finished when the next vsync signal comes, causing frame drop.

Now that we know the root cause of the lag, we can monitor the lag, so as to optimize the lag to the extreme. We can monitor application freezes from the following four aspects:

  1. Judge whether it is stuck based on the time difference between the Looper's Printer to distribute the message.

//1. 开启监听  

  Looper.myLooper().setMessageLogging(new 
                    LogPrinter(Log.DEBUG, "ActivityThread"));

//2. 只要分发消息那么就会在之前和之后分别打印消息
public static void loop() {
   final Looper me = myLooper();
   if (me == null) {
       throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }    
    final MessageQueue queue = me.mQueue;
		...
    for (;;) {
    	Message msg = queue.next(); // might block
		...

      //分发之前打印
      final Printer logging = me.mLogging;
     if (logging != null) {
        logging.println(">>>>> Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
      }
			...

      try {
       //分发消息
       msg.target.dispatchMessage(msg);
			...
      //分发之后打印
			if (logging != null) {
        logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);            
             }
       }
 }
    1. Monitor based on Choreographer callback function postFrameCallback

    2. Monitoring based on the open source framework BlockCanary

    3. Monitoring based on the open source framework rabbit-client

    How to avoid lag:

    Be sure to avoid doing time-consuming tasks in the main thread. Summarize the scenario of the main thread in Android:

    1. UI life cycle control

    2. System event handling

    3. Message processing

    4. Interface layout

    5. Interface drawing

    6. Interface refresh

    7. ...

    Another most important thing is to avoid memory jitter, and don't frequently allocate and release memory in a short period of time.

    Based on these points, there is definitely no problem with stuttering.

  • 3. Reduce memory usage

    It can be explained from the following aspects:

    1. AutoBoxing (automatic boxing): Can use small ones and never use large ones.

    2. Memory reuse

    3. Use optimal data types

    4. Enumeration type: replace Enum with annotation enumeration restriction

    5. Image memory optimization (you can talk about how they are designed from open source frameworks such as Glide)

      1. Choose the right bitmap format

      2. bitmap memory reuse and compression

      3. Multi-level caching of pictures

    6. If the basic data type does not need to be modified, it is recommended to write it as static final, because it does not need to be initialized. It can be directly packaged into the dex and can be used directly. It will not apply for memory in the class.

    7. Do not use += for string splicing, use StringBuffer or StringBuilder

    8. Don't refresh the UI in onMeause, onLayout, onDraw

    9. Try to use C++ code to convert YUV format, don’t use Java code to convert RGB format, it really takes up memory

  • 4. Reduce program exceptions

    To reduce program exceptions, then we can explain separately from stability and Crash.

    We will introduce the stability and crash of the program in detail in the fourth point.

If these are mentioned, there should be no problem in the actual development to illustrate how to solve it.

3. Have you encountered any lag problems in the project? How to troubleshoot lag? How is it optimized?

programmer:

There have been encounters, such as time-consuming operations in the main thread, frequent creation and destruction of objects, resulting in frequent GC recycling and multiple layout levels.

Interviewer:

Well, let's talk about how it is optimized.

programmer:

Here we can still expand the explanation from the display principle and optimization suggestions, refer to the following:

  1. Display principle:

  • Drawing principle:

  • Refresh principle:

    View's requestLayout and ViewRootImpl##setView will eventually call ViewRootImpl's requestLayout method, and then submit a drawing task to Choreographer through the scheduleTraversals method, and then request the vsync vertical synchronization signal from the bottom layer through DisplayEventReceiver. When the vsync signal comes, it will call back through JNI Back, post an asynchronous task to the message queue through the Handler, and finally ViewRootImpl performs the drawing task, and finally calls the performTraversals method to complete the drawing.

    The detailed process can refer to the following flowchart:

  1. The root cause of lag:

    From the perspective of refresh principle, the basic principle of lag is that there are two places that will cause frame drop:

    One is that the main thread has other time-consuming operations, resulting in no chance to call doFrame within 16 milliseconds after the vsync signal is sent;

    Another is that the current doFrame method takes too long to draw, and the frame is not finished when the next vsync signal comes, causing frame drop.

    Now that we know the root cause of the lag, we can monitor the lag, so as to optimize the lag to the extreme. We can monitor application freezes from the following four aspects:

    1. Judge whether it is stuck based on the time difference between the Looper's Printer to distribute the message.

      //1. 开启监听
        Looper.myLooper().setMessageLogging(new
                          LogPrinter(Log.DEBUG, "ActivityThread"));
      
      //2. 只要分发消息那么就会在之前和之后分别打印消息
      public static void loop() {
         final Looper me = myLooper();
         if (me == null) {
             throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
              }
          final MessageQueue queue = me.mQueue;
      		...
      
          for (;;) {
          	Message msg = queue.next(); // might block
      		...
            //分发之前打印
            final Printer logging = me.mLogging;
           if (logging != null) {
              logging.println(">>>>> Dispatching to " + msg.target + " " +
                              msg.callback + ": " + msg.what);
            }
      
      			...
            try {
             //分发消息
             msg.target.dispatchMessage(msg);
      			...
            //分发之后打印
      			if (logging != null) {
              logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
                  }
              }
          }
    1. Monitor based on Choreographer callback function postFrameCallback

    2. Monitoring based on the open source framework BlockCanary

    3. Monitoring based on the open source framework rabbit-client

  1. How to improve the smooth running of the program

    1. Layout optimization:

    1.1 Layout optimization analysis tools:

    1.2 Optimization scheme:

  2. Improve animation performance

    1. Try not to use tween animation and change to attribute animation, because performance monitoring found that the redrawing of tween animation is very frequent

    2. Use hardware acceleration to improve rendering speed and achieve smooth animation effects.

  3. How to avoid lag:

    Be sure to avoid doing time-consuming tasks in the main thread. Summarize the scenario of the main thread in Android:

    1. UI life cycle control

    2. System event handling

    3. Message processing

    4. Interface layout

    5. Interface drawing

    6. Interface refresh

    7. ...

Based on these points, there is definitely no problem with stuttering.

4. How to ensure the stable operation of the APP?

programmer:

To ensure the stability of the program, we can optimize it from knowledge points such as memory, code quality, Crash, ANR, and background survival.

Interviewer:

Then you can tell me specifically how you do it?

programmer:

1. Memory

It can be explained from the second point of memory optimization

2. Code quality

  1. The team reviewed each other's code before, to ensure the quality of the code, and can also learn the ideas of other colleagues' code.

  2. Use Link to scan the code to see if it is defective.

3. Crash

  1. By implementing the Thread.UncaughtExceptionHandler interface, the abnormal status is monitored globally. When a crash occurs, the log is uploaded to the background in time, and the plug-in package is used to repair it in time.

  2. Native online uses the Bugly framework to monitor program abnormalities in real time, and offline LAN uses Google's open source breakpad framework. If an exception occurs, collect the log upload server (the attention here is the performance problem of log upload, which will be explained by the power saving module later)

4. ANR

5. Survival in the background

Interviewer:

Well, you have a good grasp of the knowledge points.

Having said this, this level can be considered as passed.

5. Tell me about your network optimization in the project?

programmer:

Yes, this can actually be explained through the OKHTTP connection pool and Http cache (of course, the OKHTTP source code will not be analyzed here)

Interviewer:

Tell me more specifically

programmer

Having said this, let’s talk about what optimizations you have made using network frameworks such as OKHTTP (Socket connection pool, Http cache, chain of responsibility), Retrofit (dynamic proxy). Having said these, this level is generally considered to have passed.

6. What storage methods have you used in your project? Have you optimized their performance?

programmer:

Mainly used sp, File, SQLite storage methods. Which optimized sp and sqlite.

Interviewer:

So what optimizations have you made?

programmer:

If you have used other third-party databases in this piece, you can talk about their principles and how they are accessed.

7. Have you customized View in your project? What optimizations have been made to it?

programmer:

Have done it. For example, repeated drawing, and large and long pictures have been optimized.

Interviewer:

Let's talk more specifically

programmer:

Finally, I will talk about one specifically in combination with the real scene.

8. How about the power consumption of your project? Has it been optimized?

programmer:

The power consumption for 30 minutes of continuous work before optimization is 8%, and after optimization it is 4%.

Interviewer:

Then you can talk about how you optimized it.

programmer:

Because our product is a social communication software, there are audio and video calls, GPS positioning reporting, and long-term connection scenarios, so it is really difficult to optimize. But in the end, half of the power was optimized. The main optimizations are as follows:

After saying this, I will explain it in conjunction with a real optimization point of the project.

9.Have you done log optimization?

programmer:

There are optimizations. Without considering any performance before, I wrote the log directly to the file. Although I opened the thread pool to write the file, as long as the software is running, the CPU will frequently work. This also indirectly leads to power consumption.

Interviewer:

Then tell me more specifically, how did you solve this problem in the end?

programmer:

After expanding the above points, the interviewer will generally not embarrass you.

10. How big is your APK? Have you done any optimization related to APK size?

programmer:

It has been optimized. The package size of the project before optimization is 80M, and after optimization it is 50M.

Interviewer:

Talk about how it is optimized

programmer:

Based on these optimization solutions, the APK size problem can generally be solved. Finally, you can combine the steps of optimizing the APK size of your project with the above points.

to sum up

In fact, performance optimization points are closely related. For example, stuttering will involve memory and display, and startup will also involve the impact of APK dex. Therefore, performance optimization is not just a one-sided optimization, it is necessary to master the most basic optimization schemes in order to explore the performance principles in more depth.

Here is also the establishment of the source code of popular open source frameworks, such as Glide (memory) and OKhttp (network connection). The optimization is really extreme. At this point, the knowledge of performance optimization is finished, and we must digest it well.


After reading the likes, develop a habit, search "Programming Ape Development Center" on WeChat to follow this programmer who likes to write dry goods.

In addition, there is a complete test site for interviews with major Android first-line companies, and the information is updated in my [Github] . Friends who need interviews can refer to them. If it is helpful to you, you can order a Star!

Github address : https://github.com/733gh/xiongfan

Guess you like

Origin blog.csdn.net/qq_39477770/article/details/108997667