Kotlin - coprocessor and operator overloading, interview video for Java senior engineer

Posted by drums on Thu, 16 Dec 2021 23:41:44 +0100

Relationship and difference between coroutine and thread

In OS, process is the smallest unit of resource allocation, and thread is the smallest unit of task scheduling. A coroutine is a * * "micro thread", or lightweight thread * *, inside a thread. Because threads are scarce resources in the OS, the number of threads on all OS platforms has an upper limit. In normal programming, we will use thread pool to manage the number of threads. Students familiar with thread pool should know that thread pool management threads, whether core threads or non core threads, will not be created at will unless they have to.

Solving asynchronous problems with threads

  • Multithreaded synchronous programming can solve the thread safety problem of data by locking, but locking will reduce the efficiency of program execution, and there will be a potential deadlock if there are too many locks
  • The state transition of threads is completely controlled by the kernel, and programmers and developers cannot interfere
  • Threads are scarce resources and cannot be created at will. Using threads to solve asynchronous problems, thread initialization, context switching (CPU rotation), thread state switching (sleep, yield...), variable locking operation (synchronized keyword), will make the use of threads more expensive

Solving asynchronous problems with coprocessing

  • A coroutine is an optimization product running on a thread, or "micro thread". The coroutine depends on the thread, and the complex underlying logic is encapsulated in the library. When it is used, it does not need to care about the thread state
  • Using a collaboration process, developers can control the status of the collaboration process (suspend, resume), rather than relying on the underlying scheduling and time slice contention like threads.
  • A thread can run multiple coroutines, and a coroutine can also be executed on multiple threads in segments
  • The process is non blocking. After the current process is suspended, the thread resource will not be wasted. It will execute other processes (if any)
  • Compared with threads, a scarce resource in OS, coprocesses are extremely lightweight. Even if you open one million coprocesses, the pressure on the system will not be as great as a large number of threads (not to mention one million, the number of threads in linux system is 1000, and beyond this value, the system will not run normally)
  • In a word: the emergence of collaborative process has raised the control of program developers over program logic to a new level. Imagine that a function is executing. You want it to pause at one time and continue at another time. I'm afraid it's difficult to use threads. In the process of cooperation, it's easy.

Basic use

module level build In gradle, import and storage are dependent, and the latest version is recommended (the current stable version is 1.3.3)

dependencies {
    //...
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3" // If you need to use the collaboration scheduler Dispatchers, you must add this dependency
}
Creation of collaborative process

There are many ways to create a collaboration, global / independent, synchronous / asynchronous, and the "collaboration scheduler" can be specified

  • runBlocking

    fun main() {
        runBlocking {
            println("This is runBlocking Synergetic process...")
        }
    }
    
  • launch

    fun main() {
        runBlocking {
            println("This is runBlocking Synergetic process...")
            launch {
                println("This is runBlocking Internal runBlocking Synergetic process...")
                delay(2000)
                println("2000 late MS Then print")
            }
        }
    }
    
  • GlobalScope.launch

    fun main() {
        println("Compared with the main thread, the coroutines are asynchronous, that is, if you insert the coroutine logic here, the logic of the main thread will not be blocked")
        GlobalScope.launch {
            delay(3000)
            println("GlobalScope.launch Create collaboration ")
        }
        println("The main thread continues")
        Thread.sleep(5000)
    }
    
  • Global.async

    fun main() {
        runBlocking {
            val async: Deferred<String> = GlobalScope.async {
                println("This is an asynchronous coroutine. It will return a Deferred")
                delay(2000)
                "Asynchronous task return value"
            }
            println("The main thread continues:" + async.await())
        }
    
        Thread.sleep(5000)
    }
    
"Operation"

People who care about collaborative programming are generally very concerned about how convenient it can bring to our asynchronous programming. Here are a few operations that are troublesome to implement without collaborative process.

  • If there is a function, its return value needs to wait until multiple time-consuming asynchronous tasks are executed and returned, and the return values of all tasks are combined as the final return value

    fun test6(): String = runBlocking {
        var finalRes = ""
        coroutineScope {
            launch {
                delay(1000)
                finalRes = finalRes.plus("1")
            }
            launch {
                delay(2000)
                finalRes = finalRes.plus("2")
            }
    
            launch {
                delay(3000)
                finalRes = finalRes.plus("3")
            }
        }
        finalRes
    }
    
    fun main() {
        val test6 = test6()
        println("The final return value is: $test6")
    }
    

    The final returned result is (print after 3 seconds delay):

    The final return value is: 123
    
  • If there is a function, multiple network requests need to be executed sequentially, and the latter request depends on the execution result of the previous request

    import kotlinx.coroutines.*
    
    suspend fun getToken(): String {
        for (i in 0..10) {
            println("Asynchronous request executing: getToken :$i")
            delay(100)
        }
        return "ask"
    }
    
    suspend fun getResponse(token: String): String {
        for (i in 0..10) {
            println("Asynchronous request executing: getResponse :$token $i")
            delay(100)
        }
    
        return "response"
    }
    
    fun setText(response: String) {
        println("setText Execution, time:  ${System.currentTimeMillis()}")
    }
    
    fun main() {
        GlobalScope.launch(Dispatchers.Unconfined) {
            var token = GlobalScope.async(Dispatchers.Unconfined) {
                return@async getToken()
            }.await() // An asynchronous task is created, and blocking execution await is the result of blocking execution
    
            var response = GlobalScope.async(Dispatchers.Unconfined) {
                return@async getResponse(token)
            }.await() // Create an asynchronous task and execute it immediately
    
            setText(response)
        }
    
        Thread.sleep(20000)
    }
    

    Execution results:

    Asynchronous request executing: getToken :0
     Asynchronous request executing: getToken :1
     Asynchronous request executing: getToken :2
     Asynchronous request executing: getToken :3
     Asynchronous request executing: getToken :4
     Asynchronous request executing: getToken :5
     Asynchronous request executing: getToken :6
     Asynchronous request executing: getToken :7
     Asynchronous request executing: getToken :8
     Asynchronous request executing: getToken :9
     Asynchronous request executing: getToken :10
     Asynchronous request executing: getResponse :ask 0
     Asynchronous request executing: getResponse :ask 1
     Asynchronous request executing: getResponse :ask 2
     Asynchronous request executing: getResponse :ask 3
     Asynchronous request executing: getResponse :ask 4
     Asynchronous request executing: getResponse :ask 5
     Asynchronous request executing: getResponse :ask 6
     Asynchronous request executing: getResponse :ask 7
     Asynchronous request executing: getResponse :ask 8
     Asynchronous request executing: getResponse :ask 9
     Asynchronous request executing: getResponse :ask 10
    setText Execution, time:  1578904290520
    
  • An asynchronous task is currently being executed, but you suddenly don't want it to be executed. You can cancel it at any time

    fun main() {
        // Collaborative task
        val job = GlobalScope.launch(Dispatchers.IO) {
            for (i in 0..100){// Suspend 100MS every time, which is 10 seconds
                println("The coordination process is being implemented $i")
                delay(100)
            }
        }
    
        // But I cancelled the process in one second
        Thread.sleep(1000)
        job?.cancel()
        println( "btn_right End the process")
    }
    

    Execution results (100 rounds of printing should have been executed, and only 10 rounds lasted):

    Collaboration is executing 0
     Collaboration in progress 1
     The collaboration is being executed 2
     The collaboration is in progress 3
     The collaboration is being implemented 4
     The cooperation process is being implemented 5
     The collaboration is being implemented 6
     The collaboration is being implemented 7
     The collaboration is being implemented 8
     The collaboration is being implemented 9
    btn_right End the process
    
    Process finished with exit code 0
    
  • If you want a task to be executed for 3 seconds at most, it will be automatically cancelled if it exceeds 3 seconds

    import kotlinx.coroutines.*
    
    
    fun main() = runBlocking {
        println("The results of time limited tasks are:" + getResFromTimeoutTask())
    }
    
    suspend fun getResFromTimeoutTask(): String? {
        // Forget, it will ensure that the internal collaboration code is executed, so it can't be written like this
        return withTimeoutOrNull(1300) {
            for (i in 0..10) {
                println("I'm sleeping $i ...")
                delay(500)
            }
            "end of execution"
        }
    }
    

    results of enforcement

    I'm sleeping 0 ...
    I'm sleeping 1 ...
    I'm sleeping 2 ...
    The results of time limited tasks are: null
    
    Process finished with exit code 0
    

summary

As a new concept of kotlin different from java, coprocessing is to solve the problems that java can not solve, such as code bloated caused by layers of callback, such as poor control of asynchronous task execution process, etc. This chapter is limited in length and cannot be explained, but for novices, after reading this chapter, they should be able to have a general understanding of the role of collaborative process. I am also a preliminary study. After I have a deeper understanding, I will explain it in a special article.

operators overloading

concept

Human words, such as unary operator + + self addition and binary operator + addition, only support numeric types by default, such as Int. however, through operator overloading, we can make any class + + self addition and return a desired object. The logic implemented by the operator depends entirely on how we design it.

classification

By element level

  • one yuan

    expressionCorresponding function
    +aa.unaryPlus()
    -aa.unaryMinus()
    !aa.not()
    a++a.inc()
    a–a.dec()
  • binary

    expressionCorresponding function
    a+ba.plus(b)
    a-ba.minus(b)
    a*ba.times(b)
    a/ba.div(b)
    a%ba.rem(b)
    a...ba.range(b)
    a in bb.contains(a)
    a !in b!b.contains(a)
    a[i]a.get(i)
    a[i,j]a.get(i,j)
    a[i_1,...,i_n]a.get(i_1,...,i_n)
    a[i]=ba.set(i,b)
    a[i,j]=ba.set(i,j,b)
    a[i_1,...,i_n]=ba.set(i_1,...,i_j,b)
    a()a.invoke()
    a(i)a.invoke(i)
    a(i,j)a.invoke(i,j)
    a(i_1,...,i_n)a.invoke(i_1,...,i_n)
    a+=ba.plusAssign(b)
    a-=ba.minusAssign(b)
    a*=ba.timesAssign(b)
    a/=ba.divAssign(b)
    a%=ba.modAssign(b)
    a > ba.compareTo(b)>0
    a < ba.compareTo(b)<0
    a>=ba.compareTo(b)>=0
    a<=ba.compareTo(b)<=0

By implementation

  • Member function

  • spread function

Chestnuts

Summary of necessary knowledge points for Java intermediate and advanced interview in 2021

This part summarizes the common interview questions of Java so far in 2019, takes the interview core and prepares this document note to analyze the interviewer's psychology and find out the interviewer's "routine". It can be said that it is not difficult to handle more than 90% of Java intermediate and advanced interviews.

The content summarized in this section covers the knowledge points of a series of Internet mainstream advanced technologies, such as message queue, Redis cache, sub database and sub table, read-write separation, design of high concurrency system, distributed system, high availability system, SpringCloud micro service architecture and so on.

catalog:

(the above is just an outline of the overall catalogue, and each point contains the details shown below, which is a process from interview questions - Analysis of interviewer Psychology - Analysis of interview questions - perfect solution)

Some contents:

For everyone who does technology, learning cannot stop. Xiaobian has refined the core knowledge of Java so far in 2019. No matter what stage you are at now, as you can see, the content of this document is perfect for you to find an interview job or improve the breadth and depth of technology.

If you don't want to be eliminated by houlang, hurry up. The full HD version has a total of 888 pages. If you need it, you can praise + pay attention

CodeChina open source project: [analysis of Java interview questions of front-line large manufacturers + core summary learning notes + latest explanation Video]

COb-1630560593847)]

[external chain picture transferring... (IMG umrecouz-1630560593848)]

[external chain picture transferring... (img-vFT1v3aV-1630560593850)]

For everyone who does technology, learning cannot stop. Xiaobian has refined the core knowledge of Java so far in 2019. No matter what stage you are at now, as you can see, the content of this document is perfect for you to find an interview job or improve the breadth and depth of technology.

If you don't want to be eliminated by houlang, hurry up. The full HD version has a total of 888 pages. If you need it, you can praise + pay attention

CodeChina open source project: [analysis of Java interview questions of front-line large manufacturers + core summary learning notes + latest explanation Video]

Topics: Java Back-end Interview kotlin