Click on the asynchronous book, the top public account

Every day to share with you IT good books technology dry goods workplace knowledge


First of all, the interview of Toutiao is mainly divided into three or four rounds. If it is three rounds in peak season, the first is the basic interview, which usually involves about 10 questions. Recently, I interviewed a senior engineer of Mobile Android of Toutiao.

The first is a video interview with Beijing developers, which consists of theory and programming questions. Using an online programming tool, as shown below.

The first side

1, please program to achieve singleton mode, lazy and full Chinese writing method.

2. Implement Java’s producer-consumer model programmatically

Seeing this is a bit confusing, if I had written this when I graduated from university, I would have no problem, I have worked for many years, so I can only write according to my own ideas. A simpler one is to use synchronized locks and wait notify. About more knowledge can zhuanlan.zhihu.com/p/20300609

3. What is the internal structure of HashMap? Internal principles? I won’t go into details on the HashMap issue, and there is a lot of information on the subject. The only thing that needs to be noted is the difference between the internal structure of Java1.7 and 1.8 hashmaps.

4. Please briefly describe the Android event transfer mechanism. When will the ACTION_CANCEL event be triggered? On the first question, no explanation. The system documentation has this usage scenario for when ACTION_CANCEL is triggered: If you do not listen for ACTION_CANCEL when you design the slide switch of the page, if you move your finger up and down when you slide to the middle, which is outside of the switch control, then ACTION_CANCEL will be triggered instead of ACTION_UP, causing the switch button to pause in the middle. It means that when you swipe, it triggers. I don’t know if you’ve seen wechat’s long press recording, there’s a state of “release finger, cancel send”, and then ACTION_CANCEL is triggered.

5, Android interprocess communication, Liunx operating system interprocess communication. About this question is also asked a lot, here also do not explain.

6. JVM virtual machine memory structure, and their role. This question is also fairly basic, as the JVM’s memory structure is shown below.

You can learn by asking the following questions:

www.cnblogs.com/jiyukai/p/6… www.zhihu.com/question/65…

7. Describe the Android View drawing process and how wrAP_content of Android is calculated.

8, there is an integer array containing positive and negative numbers, and then it is required to move all negative numbers in the array to the left of the positive numbers, and ensure that the relative positions remain unchanged, requiring the time complexity of O(n), space complexity of O(1). For example, {10, 2, 5, 8, 4, 2, 3, 7, 12, 88, – 23, 35} after the change is {2, 4, 3, 88, – 23, 5, 8, 10, 2, 7, 12, 35}.

There are two ways to achieve this effect: first, two variables, one for the current traversal point, and one for the index value of the leftmost negative number in the array. Then we iterate through the array, and when we find a negative number, we swap it with whatever comes after that negative number, and when we’re done, we have a negative number to the left and a positive number to the right.

Second: two variables record the left and right nodes, and start traversal on both sides respectively. The node on the left continues with negative values and stops with positive values. The nodes on the right do the opposite. Then swap the left and right nodes, and start traversing again until the left and right nodes meet. The time is O(n). The space is O(1).

Obviously, the second implementation is more difficult, but as long as it satisfies the conditions.

The second plane

Intent.putextra (intent.putextra); intent.putextra (intent.putextra);

The internal structure of a bundle is actually a Map. The data passed can be Boolean, byte, int, long, float, double, string, and other primitive types or their corresponding arrays. It can also be objects or arrays of objects. When a Bundle passes objects or arrays of objects, the Serializable or Parcelable interfaces must be implemented.

2, Android IPC communication mode, whether the use of this aspect of the information is more, it is not convenient to elaborate

3. How does Android multi-touch deliver core classes

4. Principle of AsyncTask AsyncTask is a combination of Thread and Handler. Blog.csdn.net/iispring/ar… 5. Compare the android Image loading framework, there are four main differences: Android-Universal image-loader, Picasso, Glide and Fresco

Android – Universal – Image – Loader advantages: Support download progress listener (ImageLoadingListener) * can be in View scrolling pause picture loading (PauseOnScrollListener) * default implementation of a variety of memory caching algorithms (maximum first delete, use the least first delete, the least recently used, first delete, Disadvantages: no longer maintained after 2015, the library needs to be configured before use.

Picasso was advantages: Small package (100K) * Cancel loading of out-of-view image resources * Complete complex image conversion with minimal memory * Automatically add secondary cache * Task scheduling priority processing * Adjust the number of concurrent threads according to network type * Local cache of images is handed over to OkHTTP, also produced by Square. Control the expiration time of images. Disadvantages: The function is relatively simple, cannot realize the “local cache” function.

Glide advantages: * Life cycle integration (manage image loading requests according to the Activity or Fragment life cycle) * Efficient processing of bitmaps (reuse and active recycling of bitmaps, * Efficient cache strategy, flexible (Picasso only caches raw images, Glide caches multiple sizes), fast loading and low memory overhead (the default Bitmap format makes memory overhead half that of Picasso). Disadvantages: The method is more complicated, because it is equivalent to an improvement on Picasso, the package is larger (500K), the impact is not very big.

Disadvantages of Fresco: The biggest advantage is bitmap loading under 5.0 (minimum 2.3). Under 5.0, Fresco places images in a special memory area (the Ashmem area) * greatly reduces the OOM (the OOM is processed in the lower Native layer, so images no longer take up the App’s memory) * applies to scenarios that require high performance loads of images. Disadvantages: large package (2~3M) * complex usage * low-level involvement in c++ domain

5. Why doesn’t looper.loop () in the main thread loop indefinitely cause ANR? Activitythread. Java is the main thread entry class. The main function of ActivityThread. Java reads as follows.

Looper.loop() = looper.loop ()

Obviously, the main method of ActivityThread is just a message loop, and once you exit the message loop, your application exits. So this endless loop doesn’t cause ANR anomalies?

Note: Since Android is event-driven, looper.loop() continuously receives and handles events, and every touch or Activity is under the control of Looper.loop() for its life cycle. If it stops, the application stops. Looper.loop() is blocked only by a single message or its processing, not by looper.loop (). In other words, our code is actually in this loop to execute, of course, does not block. Take a look at the handleMessage source code:

As you can see, the Activity’s life cycle depends on the main thread’s looper. loop, which takes action when different messages are received.

If a message takes too long to process, such as onCreate() or onResume(), then the next message, such as a user click, can’t be processed, and the whole loop will stall and become ANR over time.

Conclusion: The looer.loop () method may block the main thread, but as long as its message loop is not blocked, it can always handle events without generating ANR exceptions.

6. Some principle knowledge of picture frame

7, other Android modular development, hot update, componentization and other knowledge.

The mainstream framework for Android interviews

In Android interview, we will often be asked about some development frameworks used in Android development, such as common network request framework Retrofit/OkHttp, component communication framework EventBus/Dagger2, asynchronous programming RxJava/RxAndroid, etc. This article will sort out the above framework for the interview.

EventBus

EventBus is an Android publish/subscribe EventBus that simplifies communication between components and makes code more brief, but it can also make code more auxiliary if abused. Interview with EventBus:

(1) EventBus is obtained by annotation + reflection

Usage of annotations: @Retention(retentionPolicy.runtime) indicates that this annotation is available at RUNTIME; otherwise using CLASS or SOURCE is discarded at RUNTIME. Fetching classes and methods by reflection: Because the mapping is actually a class mapping to methods of all such objects, the class and annotated methods should be retrieved by reflection and the method and object saved as a calling entity.

(2) Use ConcurrentHashMap to save the mapping relationship

Call entity construction: Weak references should be used instead of strong references in the calling entity for Object, the Object that actually executes the method, because the Map’s static life cycle may be longer than that of the called Object, and memory leaks can occur if strong references are used.

Description: Concurrent programming practice, ConcurrentHashMap is a frequently used data structure, compared with the Hashtable and Collections. SynchronizedMap (), ConcurrentHashMap provides better write concurrency on a thread-safe basis while reducing read consistency requirements. Details you can look at the following article: www.importnew.com/22007.html.

(3) Method execution

Methods are dispatched using the Dispatcher, asynchronous methods are handled using the thread pool, synchronization is executed directly, and UI threads create a Handler using the MainLooper and post it to the main thread for execution.

Retrofit

At the heart of EventBus is the dynamic proxy technology.

Dynamic proxy in Java:

First of all, dynamic proxy is different from static proxy. In the proxy mode, the proxy class and the actual implementation class should implement the same interface at the same time, and the same code should be added before and after the methods defined by each interface. In this way, many method proxy classes may need to be repeated. A dynamic proxy class simply implements the Invoke method in the InvocationHandler interface, When dynamic proxies are needed, A final auto-generated proxy object A* is generated based on the interface and A proxy object A that implements InvocationHandler. This way the final proxy object A* will execute the Invoke function of InvocationHandler’s proxy object A, no matter what method it calls, and you can implement the real proxy logic in this invoke function.

The implementation mechanism of dynamic Proxy is actually the process of generating A specific A* object by using proxy. newProxyInstance function to generate bytecode of A* class of dynamic Proxy object A. This A* class has several characteristics. First, it needs to implement the interface passed in. The second is that all interface implementations call A’s invoke method and pass in the corresponding call to the actual method (that is, the method in the interface).

Dynamic agents in Retrofit

It’s nice to use dynamic proxies in Retrofit, but not for real proxies, it’s just for a very important function of dynamic proxies, which is the “interception” function. We know that all method executions of the automatically generated A* object in the dynamic proxy will invoke the invoke method of the actual proxy class A, and we will implement the logic of the real proxy in invoke. In fact, all methods of A* are intercepted by the A object. Retrofit’s job is to make proxies as simple as method calls.

Create a ServiceApi object with this Retrofit object and call the function through the getAuthor function.

So a network Call, you just set it up with annotations in the interface that you create, and then you create an API with Retrofit and Call it, and it automatically creates an Okhttp Call. The code for Retrofit’s create() function is as follows:

Can we see how to create an API object from an interface class? Is to use the interception technique in dynamic proxy, by creating A dynamic proxy object that conforms to this interface, A? This is the anonymous class created here, which internally implements invoke, so that A* calls the invoke function of A, which is intercepted and actually runs invoke. Invoke, on the other hand, generates a qualified Okhttp Call object based on the annotation of the called Method and makes the actual request.

Retrofit effect

Retrofit is actually designed to make Okhttp easier to use, because Okhttp is all about building a Call, and most of the process of building a Call is similar, and Retrofit uses a proxy mechanism to dynamically create a Call, and the Call creation information comes from your annotations.

OkHttp3

For OkHttp3 you can visit the following blog link: OkHttp3 source code analysis. This article explains OkHttps from the following aspects: OkHttp3 source code analysis [overview] OkHttp3 source code analysis [reuse connection pool] OkHttp3 source code analysis [cache strategy] OkHttp3 source code analysis [DiskLruCache] OkHttp3 source code analysis [task queue]

Request task queue

Okhttp uses a thread pool for the actual execution of asynchronous network tasks and a task queue model for task management, similar to the reverse proxy model for servers. Okhttp uses the Dispatcher to maintain a queue of running tasks and a wait queue. If the current number of concurrent tasks is less than 64, they are placed in the execution queue and executed in the thread pool. If the current number of concurrent tasks is greater than 64, the dispatcher is queued. After each task is completed, the dispatcher’s finish function is called in the finally block to check whether there are any free tasks in the wait queue. If there are any, the dispatcher is queued. Okhttp uses the task queue model for task execution and scheduling.

Multiplexing connection pool

Http uses TCP connection has long connection and short connection, for the frequent communication to access a server, the use of short connection is bound to cause a lot of time consumption in the establishment of connection; And the long connection of the long time useless hold will cause you to waste resources. Okhttp uses sockets to establish stream connections. If you do not close the connection manually, it will cause memory leaks. Therefore, we do not close the connection. In Okhttp, it manages connections in a similar way to reference counting. In this case, the count object is StreamAllocation, and aquire and release operations are performed repeatedly. The two functions actually change the List

> size in Connection. The amount of Allocation in the List is also the Refference Count. If the Count is 0, the connection is idle and not in use. In this case, an elimination algorithm is required to reclaim the connection.

A thread pool is maintained within the connection pool. This thread pool runs a cleanupRunnable, which is actually a blocking runnable, with an infinite loop that calls wait after the cleanup is complete, depending on the return value of cleanup. Wait until the time is up before cleaning up. The relevant codes are as follows:

The Cleanup function is executed as follows:

Traverse all realConnections in the Deque, marking the leaking connections;

If the marked connection is sufficient (more than 5 idle socket connections with a keepalive time of more than 5 minutes), the connection is removed from the Deque, the connection is closed, and 0 is returned, that is, wait(0) will be executed to remind scan again immediately.

If (there is still room for 5 connections, but there is a possibility of leaking connections (i.e., idle time is about to reach 5 minutes)), return the remaining time for the connection to expire for the next cleanup;

If (all connections are active), the default keep-alive time is returned, which is 5 minutes before cleanup.

If (there are no connections), -1 is returned, breaking the cleanup loop.

Note: “Concurrent” ==(” idle “+” active “)==5, not that a concurrent connection is necessarily an active connection.

How do you mark free connections? We also said, if a connection with reference to 0, so that it is free, pruneAndGetAllocationCount are used to calculate reference number in it, as the reference counting process. The algorithm for marking a Reference to 0 is simple. It simply iterates through its List

> and removes all weak references that are already null. The number of references left is the current number of references. PruneAndGetAllocationCount function source code is as follows:

​RxJava

Since 2015, there has been a wave of asynchronous programming on the front end. In the process of mobile Android programming, the concept of observer and observed is often heard.

The observer communicates with the observed

Observable creates an observer object using the create function.

Observable constructors look like this:

It creates an Observable we’ll call Observable1, which stores the incoming OnSubscribe object as OnSubscribe, which is very important, as we’ll see later.

OnSubscribe method

Rxjava transformation process

Data transformations are common in RxJava, such as the map function, filtmap function, and lift function.

Lift function

We can see here that we’ve created a new Observable, which we’ll call Observable2, which means that when we execute the map, we actually return a new Observable, Our subsequent subscribe function actually executes on our newly created Observable2, and it calls our new call function, the call function of Observable2 (in bold). Let’s look at the implementation of this operator’s call. Here the call is passed in to our Subscriber1 object, which is the processing object that calls the final subscribe.

Call the function

Transformer here is the func function that we pass in during the map call, i.e. the specific process of transformation. So if we look at onSubscribe. Call, who’s onSubscribe here? That’s the onSubscribe object that we Observable1 stores, the one that we said was important. And this O (back again) is our Subscriber1. It can be seen here that after calling the conversion function, we still call the original Subscriber1’s onNext, and the final event is converted to our result.

Scheduler Process

The most useful feature of RxJava is that it provides easy thread switching, but its principle is still lift. The principle of subscribeOn() is to create a new Observable that sends the start execution of its call process to the desired thread. ObserveOn () puts the thread switching logic in its own Subscriber. Post the execution of the final Subscriber1 to the required thread.

As can be seen from the figure, subscribeOn() and observeOn() both do the work of thread switching (” schedule… “in the figure). Parts). The difference is that the thread switch of subscribeOn() occurs in OnSubscribe, that is, when it notifies the next level of OnSubscribe, the event has not been sent yet, so the thread control of subscribeOn() can be affected from the beginning of sending the event. The thread switch for observeOn() happens in its built-in Subscriber, that is, when it is about to send an event to the next Subscriber, so observeOn() controls the thread behind it.

Why only the first subscribeOn() is valid? Because it starts with the notification and sends all subsequent executions to the desired thread for execution, but subsequent deliveries are affected by those above it (but executed after it), and if there is a subscribeOn() attached to it, they are sent to a different thread so that they are not under its control.


This article comes from asynchronous community, the author: Xiangzhihong, the work “Toutiao Android Interview”, unauthorized, prohibited reprint.

Recommended reading

May 2018 Book List (bonus at the end)

A list of new books for April 2018

Asynchronous books the most complete Python book list

A list of essential algorithms books for programmers

The first Python neural network programming book

Long press the QR code, you can follow us yo

I share IT articles with you every day.


If you reply “follow” in the background of “Asynchronous books”, you can get 2000 online video courses for free. Recommend friends to pay attention to according to the prompts to get the gift book link, free asynchronous E reading version of a book. Come and join us!

Click to read the article for more information

Read the original