April 17, 2018, phone interview

First of all, the interviewer is very nice. I am very grateful to have such an interview experience. I am very grateful to the interviewer for the patient interview, which gave me the opportunity to exercise and improve.

Here's a summary of some of the interview questions:

1. Pay attention to data structures and common algorithms, 2. Learning must have a clear route and purpose, 3. You cannot simply call the SDK, but also understand the implementation principle of the code.

Here are the interview questions:

Introduce yourself (talk about something you do)

Database (MySQL), how to design a database?

Web framework (Spring framework, IOC)?

    Inversion of control, the transfer of control of the component object, is transferred from the program code itself to the external container, and the assembly and management of the object component are realized through the container. IOC implementation principle: The implementation principle of IoC in Spring is the factory mode plus reflection mechanism. The factory mode provides an interface for creating objects, which can be divided into simple factory mode, factory method mode and abstract factory mode; the reflection mechanism is to find the name of a class from an object, call the getClass() method from the instantiated object, and get a complete " package" "class" name.
How to deal with the collision between hashMap and hashCode and hashCode?

    hashMap, stored out of order, and keys are not allowed to be repeated; the hashCode method returns a hash code value to the object, which is used for hash tables, such as hashMap . HashMap can accept null key values ​​and values, HashMap is non-synchronized; HashMap is fast, and HashMap stores key-value pairs; the premise of Hash is to implement equals() and hashCode() two methods, then the role of HashCode() is to guarantee The object returns a unique hash value, but when two objects calculate the same value, a collision occurs. The methods that can be taken are: open address method, re-hash method, chain address method (zipper method) and establishing a public overflow area

①The zipper method is simple to deal with conflicts, and there is no accumulation phenomenon, that is, non-synonymous words will never conflict, so the average search length is shorter;
②Because the node space on each linked list in the zipper method is dynamically applied, it is more suitable for When the table length cannot be determined before the table is built;
③ The open addressing method requires a small filling factor α to reduce conflicts, so a lot of space will be wasted when the node scale is large. In the zipper method, α≥1 is preferable, and when the node is large, the pointer field added in the zipper method can be ignored, thus saving space; ④In
the hash table constructed by the zipper method, the operation of deleting a node is easy to implement.

CurrentHashMap?

    The main difference between ConcurrentHashMap, ConcurrentHashMap and Hashtable in the three concurrent collection types (concurrent, copyonright, queue) is  the granularity of the lock and how to lock. Hashtable is implemented by locking the entire hash table; while ConcurrentHashMap is implemented by locking bucket ( or segment), the read concurrency of ConcurrentHashMap, because the lock is not used in most of the time of reading, so the read operation is almost completely concurrent operation, and the granularity of the write operation lock is very fine, more than before fast

, the entire table needs to be locked only for operations such as size. When iterating, ConcurrentHashMap uses another iteration method that is different from the fast-fail iterator of traditional collections, called weakly consistent iterator. In this iterative method, when the iterator is created and the collection changes again, it will no longer throw ConcurrentModificationException, but new new data will not affect the original data when the iterator is changed, and the head pointer will be replaced after the iterator is completed. New data, so that the iterator thread can use the original old data, and the writing thread can also complete the changes concurrently. More importantly, this ensures the continuity and scalability of concurrent execution of multiple threads, which is the key to performance improvement. There are three main entity classes in ConcurrentHashMap: ConcurrentHashMap (the entire Hash table), Segment (bucket), and HashEntry (node).

Java memory model?

    The Java Memory Model is the Java Memory Model, or JMM for short. JMM defines how the Java Virtual Machine (JVM) works in computer memory (RAM). The JVM is a virtual model of the entire computer, so the JMM belongs to the JVM. The Java memory model defines the visibility of shared variables between multiple threads and how to synchronize shared variables when needed.

    在并发编程领域,有两个关键问题:线程之间的通信同步线程的通信是指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种共享内存消息传递共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信,典型的共享内存通信方式就是通过共享对象进行通信。消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行通信,在java中典型的消息传递方式就是wait()notify()同步是指程序用于控制不同线程之间操作发生相对顺序的机制。在共享内存并发模型里,同步是显式进行的。必须显式指定某个方法或某段代码需要在线程之间互斥执行。在消息传递的并发模型里,由于消息的发送必须在消息的接收之前,因此同步是隐式进行的。Java线程之间的通信总是隐式进行.

    JMM决定一个线程对共享变量的写入何时对另一个线程可见。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。在JVM内部,Java内存模型把内存分成了两部分:线程栈区和堆区.当多个线程同时操作同一个共享对象时,如果没有合理的使用volatile和synchronization关键字,一个线程对共享对象的更新有可能导致其它线程不可见。在执行程序时,为了提高性能,编译器和处理器会对指令做重排序。但是,JMM确保在不同的编译器和不同的处理器平台之上,通过插入特定类型的Memory Barrier来禁止特定类型的编译器重排序和处理器重排序,为上层提供一致的内存可见性保证。如果两个操作访问同一个变量,其中一个为写操作,此时这两个操作之间存在数据依赖性。 编译器和处理器不会改变存在数据依赖性关系的两个操作的执行顺序,即不会重排序。在JMM中,如果一个操作的执行结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系,这个的两个操作既可以在同一个线程,也可以在不同的两个线程中。

关于Hadoop,是否使用过?

Python的闭包、装饰器和生成器?

    python中的闭包从表现形式上定义为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).闭包=函数块+定义函数时的环境,一个闭包就是调用了一个函数A,这个函数A返回了一个函数B。这个返回的函数B就叫做闭包。在调用函数A的时候传递的参数就是自由变量。

    装饰器的功能是将被装饰的函数当作参数传递给与装饰器对应的函数(名称相同的函数),并返回包装后的被装饰的函数,装饰器就是一种的闭包的应用,只不过其传递的是函数。

    闭包的最大特点是可以将父函数的变量与内部函数绑定,并返回绑定变量后的函数(也即闭包),此时即便生成闭包的环境(父函数)已经释放,闭包仍然存在,这个过程很像类(父函数)生成实例(闭包),不同的是父函数只在调用时执行,执行完毕后其环境就会释放,而类则在文件执行时创建,一般程序执行完毕后作用域才释放,因此对一些需要重用的功能且不足以定义为类的行为,使用闭包会比使用类占用更少的资源,且更轻巧灵活。

    生成器是一种用普通的函数语法定义的迭代器。任何包含yield语句的函数称为生成器,每次产生多个值,每次产生一个值,函数就会被冻结:即函数停在那点等待被重新唤醒。函数被重新唤醒后就从停止的那点开始执行。生成器是由两部分组成:生成器的函数和生成器的迭代器。生成器的函数是用def语句定义的,包含yield的部分,生成器的迭代器是这个函数返回的部分。生成器的方法有:send()、yield()、throw()、close()等。

快速排序算法?

      快速排序采用了一种分治的策略,通常称其为分治法。将原问题分解为若干个规模的更小但结构与原问题相似的子问题,递归地解决这些子问题,然后将这些子问题的解组合为原问题的解。

    设当前待排序的无序区为R[low...high],利用分治法将快速排序的基本思想描述为:

    ①分解。在R[low...high]中任选一个记录作为基准(Pivot),以此基准将当前的无序区划分为左、右两个较小的子区间R[low...pivotpos-1]和R[PIVOTPOS+1...high],并使左边子区间中所有记录的关键字均小于或等于基准记录(pivot)的关键字pivot.key,右边子区间的所有记录的关键字均大于或等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无需参加后续的排序。

   划分的关键是要求出基准记录所在的位置pivotpos。划分的结果可以简单地表示为(pivot=R[pivotpos]):

    R[low...pivotpos-1].keys≤R[PIVOTPOS].key≤R[pivotpos+1...high].keys,其中low≤pivotpos≤high

   ②求解:通过递归调用快速排序对左、右子区间R[low...pivotpos-1]和R[pivotpos+1...high]快速排序

   ③组合。因为当“求解”步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,“组合”步骤无须做什么,可看作是空操作。

   划分算法Partition

   第一步:(初始化)设置两个指针i和j,它们的初值分别为区间的下届和上界,即i=low,j=high。选取无序区的第一个记录R[i](即R[low])作为基准记录,并将它保存在变量pivot中。

   第二步:令j自high起向左描述,直到找到第一个关键字小于pivot.key的记录R[j]。将R[j]移至i所在的位置上,这相当于R[j]和基准[i](即pivot)进行了交换,使关键字小于基准关键字pivot.key的记录移到了基准的左边,交换后,R[j]中相当于pivot;然后令i指针自i+1位置开始向右扫描,直至找到第一个关键字大于pivot.key的记录R[i],将R[i]移动i所指的位置上,这相当于交换了R[i]和基准R[j],使关键字大于基准关键字的记录移到了基准的右边,交换后,R[i]中又相当于存放了pivot;接着令指针j自位置j-1开始向左描述,如此交替改变扫描方向,从两端各自往中间靠拢,直至i=j时,i便是基准pivot最终的位置,将pivot放在此位置上就完成了一次划分。


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325646147&siteId=291194637