Unexpected joy
Because of the epidemic, it took a lot of time to come back from abroad. I thought I couldn't catch the last bus of school recruitment. With a try mentality, I submitted Baidu's resume. Unexpectedly, I received Baidu's interview notice.
No nonsense. Talk about what you said during the interview. By the way, resume the interview and record all the unsolved problems.
Internship experience
Briefly smell the experience of internship and the technology used. Ask questions based on the content mentioned. For example, sql statements.
It mentioned how to calculate the duplicate data of a column in the table.
I thought of at least two ways:
One is:
Select count(1) from xxx where name = 'zhangsan';
The other is to use Group by.
As a result, I can't remember how to use Group by at once. (cover your face)
- Group by
The GROUP BY statement is used to group a result set according to one or more columns in combination with an aggregate function.SELECT column_name, aggregate_function(column_name) FROM table_name WHERE column_name operator value GROUP BY column_name;
- Having
The reason for adding the HAVING clause in SQL is that the WHERE keyword cannot be used with aggregate functions. The HAVING clause allows us to filter the grouped groups of data.SELECT column_name, aggregate_function(column_name) FROM table_name WHERE column_name operator value GROUP BY column_name HAVING aggregate_function(column_name) operator value;
For details, please see the SQL GROUP BY statement rookie tutorial
Project experience
He talked about the projects he did as a student and what technology was used in them. Because the project called the third-party api, the interviewer thought it was a distributed system and asked me how to ensure the consistency of data.
At that time, I didn't know how to answer, but I just said the logic of the code. After reading the following articles, I should use the method of avoiding distributed transactions - business integration. Um. The result is performance degradation. (cover your face)
6 schemes:
- Avoiding distributed transactions - business integration
- Classic scheme - eBay mode (distributed processing tasks are executed asynchronously through message log)
- Qunar distributed transaction scheme (convert distributed transactions into multiple local transactions, and then achieve final consistency by means of retry)
- Distributed consistency scheme in the process of establishing mushroom Street transaction
- Distributed service DTS scheme of Alipay and ant financial cloud
- Data consistency scheme of rural credit network
For details, please see: 6 schemes to ensure data consistency of distributed system
Design mode
When explaining the project, the design patterns used were mentioned. Therefore, the interviewer asked the following questions based on the design pattern. What are singletons and their types. What is the difference between strategy mode and state mode and their essence. I understand the concepts of singleton, strategy and state pattern, but as soon as I go deeper, I am blind again. Here is a tutorial.
Singleton mode
Singleton Pattern is a creation mode.
This pattern involves a single class that is responsible for creating its own objects while ensuring that only a single object is created. This class provides a way to access its unique object, which can be accessed directly without instantiating the object of this class.
The definition of Head First design pattern is: Singleton pattern (different translation) ensures that a class has only one instance and provides a global access point.
Main solution
A globally used class is frequently created and destroyed.
advantage
- There is only one instance in memory, which reduces the overhead of memory, especially the frequent creation and destruction of instances (such as the homepage page cache of the school of management).
- Avoid multiple occupation of resources (such as writing files).
shortcoming
- There is no interface and cannot be inherited, which conflicts with the principle of single responsibility. A class should only care about the internal logic and not how to instantiate it outside.
Usage scenario
- Production unique serial number required
- The counters in the WEB do not need to be added to the database every time they are refreshed, but are cached first with a single instance.
- Creating an object consumes too many resources, such as the connection between I/O and database.
matters needing attention
The getInstance() method needs to use the synchronization lock synchronized (Singleton.class) to prevent multiple threads from entering at the same time, causing the instance to be instantiated multiple times.
What are the types of singleton patterns
Hungry man mode (thread safe, available)
Note the static keyword, which indicates that the pattern completes the creation of the object when the class is loaded. The advantage is that it is fast to get objects, but slow to load classes.
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){ } public static Singleton getInstance() { return instance; } }
Lazy mode (thread unsafe, unavailable)
Lazy mode declares a static object that is initialized when the user first invokes it.
Although it saves resources, it needs to be instantiated for the first time, which is slower, and conflicts will occur in multiple threads.
For example, when thread A and thread B reach line 6 at the same time, A and B will create an instance respectively.
public class Singleton { private static Singleton instance; private Singleton (){ } public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
Lazy mode (thread safe, not recommended)
The synchronized keyword modifies the getInstance method to ensure that it is called by only one thread at a time. However, after creation, under certain requirements, getInstance does not need to be locked, and a single instance can be called by multiple threads at the same time. At this time, it seems that unnecessary synchronization overhead is caused.
public class Singleton { private static Singleton instance; private Singleton (){ } public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
Double check mode (DCL, thread safety, recommended)
In this mode, a synchronization lock is added to the instantiation process. At the same time, a second null judgment is added to the synchronization block. In the case of delayed loading, thread safety is guaranteed.
In this way, even if thread B is true in line 6 as mentioned above, but
- First, it will enter the blocking state because it does not obtain the lock.
- After obtaining the lock, determine whether it is null, which also prevents secondary creation.
In addition, instance is modified with volatile to ensure order and prevent code rearrangement. Why?
First, in java, the process of new is not atomic. It is divided into three steps:
- Apply for space.
- Create an instance in a space.
- Assign space to instance. (at this time, instance is not null)
The JVM will optimize the code when compiling (the optimization order is one of them), as long as the optimized code does not change the output result. In this process, the of 2 and 3 may be rearranged, causing other threads to obtain instance s with allocated space but no instantiation.
public class Singleton { //Ensure the order of instance. private volatile static Singleton instance; private Singleton (){ } public static Singleton getInstance() { if (instance== null) { //To prevent the above-mentioned, thread B also creates a singleton when it determines that instance == null synchronized (Singleton.class) { if (instance== null) { instance= new Singleton(); } } } return singleton; } }
Although DCL solves the problems of resource consumption, redundant synchronization and thread safety to a certain extent, it still has the problem of failure in some cases, that is, DCL failure. In java Concurrent Programming practice, it is suggested to replace DCL with static internal class singleton mode.
Static inner class singleton mode (thread safe, highly recommended)
This mode ensures thread safety, delayed loading and high efficiency.
This model is similar to the hungry man model, but different.
Similarities:
- Class loading mechanism is adopted to ensure that there is only one thread initialization instance
difference:
- In the hungry man mode, the Singleton class is instantiated when loaded, without the role of lazy loading
- In the static internal class mode, when the Singleton class is loaded, it will not be instantiated immediately. Only when getInstance method is called can SingletonHolder class be loaded to complete instantiation of sInstance.
public class Singleton { private Singleton(){ } public static Singleton getInstance(){ return SingletonHolder.sInstance; } private static class SingletonHolder { private static final Singleton sInstance = new Singleton(); } }
For details, please see: design mode (II) seven writing methods of single example mode_ Liu Wangshu's column - CSDN blog
For details, please see: comparison of seven writing methods of singleton mode_ ybb520chongren_ Blog - CSDN blog
For details, please see: a thorough understanding of singleton mode and multithreading_ Rico's blogs CSDN blog
Strategy mode
The book "Head First design pattern" defines the policy pattern in this way: the policy pattern defines the algorithm family and encapsulates them respectively so that they can be replaced with each other. This pattern makes the change of the algorithm independent of the customers who use it.
Therefore, the main solution of the strategy mode is to encapsulate a set of replaceable behaviors (the behavior of mutual replacement is change) into a set of algorithms under one interface. So as to achieve the effect of packaging changes, modification and closing, and extension development.
Note: these behaviors may be increased or modified due to business needs. If you use inheritance or implement interfaces, you still need to modify a lot of code, which can not achieve the effect of closing the modification. The policy pattern uses a combination form, taking an interface as a member variable. Different algorithms are given to actors according to business requirements. The algorithm is implemented by a special implementation class. Even if it is added, modified or deleted, it will not affect the original code.
Main solution
When there are many similar algorithms, using if... else is complex and difficult to maintain.
Note: this sentence is quoted from Strategy mode | rookie tutorial But personally, I don't think this sentence is right at all. The reasons are as follows:
- Indeed, it is a good idea to separate similar algorithms, which encapsulates changes. For extension development, close for modification. However, this does not solve the complexity and difficulty of maintaining multiple if... else.
- The algorithm is independent. There is no need for multiple judgments to select specific operations in the method, which only means that the judgment has been moved out (see the code demo below). Still difficult to maintain.
- The mode that really solves multiple if... else problems should be factory mode. Only when the factory mode is used together with the strategy mode can the effect be achieved.
advantage
- The algorithm can be switched freely.
- Avoid using multiple conditional judgments. (I don't agree with it personally. It can only be avoided by cooperating with the factory model)
- Good expansibility to avoid class expansion. When a function of a class has multiple implementations, you can define a policy interface and delegate the function implementation to the policy implementation class.
shortcoming
- Policy classes will increase.
- All policy classes need to be exposed. Against Dimitri's law. The Context class needs to know what kind of policy class there is before it can create a specific policy according to the condition new. Similarly, it can be solved with the factory model.
Usage scenario
- If there are many classes in a system, and the only difference between them is their behavior, then using the policy pattern can dynamically let an object choose one behavior among many behaviors.
- A system needs to dynamically choose one of several algorithms. 3. If an object has a lot of behaviors, without appropriate patterns, these behaviors can only be realized by multiple conditional selection statements.
matters needing attention
If there are more than four policies in a system, we need to consider using mixed mode to solve the problem of policy class expansion.
Implementation code
1. Create policy class interface
public interface Strategy { public int doOperation(int num1, int num2); }
2. Create the implementation class of the interface
//Addition operation public class OperationAdd implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 + num2; } } //Subtraction operation public class OperationSubtract implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 - num2; } } //Multiplication operation public class OperationMultiply implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 * num2; } }
3. Create Context class
Context class is generally the subject of behavior.
public class Context { private Strategy strategy; public Context(Strategy strategy){ this.strategy = strategy; } public int executeStrategy(int num1, int num2){ return strategy.doOperation(num1, num2); } }
4. Example of strategic mode
As mentioned above, it can't solve the problem of multiple judgments. It just moves the judgment to Context or Demo
Class. Demo sets different behaviors (algorithms) for the actor (Context) according to business requirements (multiple judgments).
public class StrategyPatternDemo { public static void main(String[] args) { if (arg[1] == "+") { Context context = new Context(new OperationAdd()); System.out.println("10 + 5 = " + context.executeStrategy(10, 5)); } if (arg[1] == "-") { context = new Context(new OperationSubtract()); System.out.println("10 - 5 = " + context.executeStrategy(10, 5)); } if (arg[1] == "*") { context = new Context(new OperationMultiply()); System.out.println("10 * 5 = " + context.executeStrategy(10, 5)); } } }
For details, please see: strategy mode rookie tutorial
For details, please see: in depth analysis of policy mode_ Blog column of tugani
For details, please see: polymorphism in design pattern - detailed explanation of strategy pattern - takumiCX - blog Garden
State mode
State mode and policy mode are very similar. They both extract behavior and turn it into an interface and its implementation class. Change the behavior by replacing the implementation class.
The definition of state pattern in Head First design pattern is as follows: an object is allowed to change its behavior when its internal state changes, and the object looks as if it has modified its class.
Main solution
The behavior of an object depends on its state (properties), and its related behavior can be changed according to its state change.
advantage
- Encapsulates the conversion rules.
- Enumerate possible states. Before enumerating States, you need to determine the state type.
- Put all the behaviors related to a certain state into one class, and you can easily add new states. You can change the behavior of the object by changing the state of the object.
- Allow state transition logic to be integrated with state objects instead of a huge conditional statement block.
- Multiple environment objects can share a state object, thus reducing the number of objects in the system.
shortcoming
- The use of state mode will inevitably increase the number of system classes and objects.
- If the structure and mode of the program are not used properly, it will lead to the confusion of the structure and mode of the program.
- The state mode does not support the "opening and closing principle" very well. For the state mode that can switch states, adding a new state class requires modifying the source code responsible for state transition, otherwise it cannot switch to the new state, and modifying the behavior of a state class also requires modifying the source code of the corresponding class.
Usage scenario
The condition of state transition inside the object is too complex, and the client does not need to know the specific state before calling.
By transferring the state judgment logic to a series of state classes representing different states, the complex judgment logic can be simplified. Maintain the opening and closing principle to facilitate maintenance.
matters needing attention
Use the state mode when the behavior is constrained by the state, and there are no more than 5 states.
Implementation code
1. Create status class interface
public interface State { public void doAction(Context context); }
2. Create the implementation class of the interface
Simplify the multiple judgment logic through doAction(), making the code logic clearer and easy to maintain.
State transition:
//Start state public class StartState implements State { public void doAction(Context context) { if (context.getOn() == true) { System.out.println("Player is in start state"); //In addition to making simple judgments, you can also change the state of the context class after the business logic is completed. context.setOn(false); } else { context.setState(new StopState()); context.doAction(); } } } //Stop operation public class StopState implements State { public void doAction(Context context) { if (context.getOn() == false) { System.out.println("Player is in stop state"); //In addition to making simple judgments, you can also change the state of the context class after the business logic is completed. context.setOn(true); } else { context.setState(new StartState()); context.doAction(); } } }
3. Create Context class
Context class is generally the subject of behavior. Context directly calls the state to implement the behavior.
public class Context { private boolean on; private State state; public Context() { state = new StartState(); on = true; } public void setState(State state) { this.state = state; } public State getState() { return state; } public boolean getOn() { return on; } public void setOn(boolean on) { this.on = on; } public void doAction() { state.doAction(this); } }
4. Status mode example
After creating the Context, you can call setOn() as needed to modify the state of the object. In addition, the status on of Context will change automatically after the behavior is implemented.
public class StatePatternDemo { public static void main(String[] args) { Context context = new Context(); context.doAction(); //context.setOn(true); context.doAction(); } }
For details, please see: status mode | rookie tutorial (please don't learn the code implementation in this link. Its code is wrong and misleading.)
For details, please see: twin brothers of strategy mode - Summary of in-depth review of state mode
The essential difference between strategy mode and state mode
In the policy mode, the implementation classes of the same interface are equal.
In state mode, the implementation class relationship of communication interface is not equal, and can only change from one state to another.
That's what the interviewer said.
The first sentence is understandable.
The second sentence is similar to the meaning of state machine. The next state is determined by the previous state [+ input variable (not necessarily required)]. It's not that you want to change into any behavior mode.
Take chestnuts for example: ABC has three behavior patterns. Input variables X1,X2
The transformation of behavior is not directly passed into an implementation class. Instead, you need to logically transform the state. As shown in the figure above, B can never be transformed into A. However, in the policy mode, you can directly replace B with A.
In other words, the implementation classes of the policy pattern can be replaced at will (i.e. equality). However, the implementation class replacement of state mode must comply with the transformation logic of state.
For details, please see: twin brothers of strategy mode - Summary of in-depth review of state mode
Java
Atomicity
-
What is atomicity?
Atomicity is a property in java, which means that operations cannot be separated. For example, the count + + operation will be executed at one time
Will not be interrupted. The new operation is divided into three steps:
1. Get memory space
2. Instantiate memory space
3. Assign memory space to variable
This process will be disrupted by concurrent operations, so new is not atomic. -
Function: atomic operation can ensure data thread safety.
-
How?
- reentrantLock
- Synchronized keyword
- The operations of the atomic package class in JUC are atomic.
visibility
- What is visibility?
Visibility means that when multiple threads access the same variable, one thread modifies the value of the variable, and other threads can immediately see the modified value.
summary
Although the result is not very ideal, the interviewer is a very kind person. I am very grateful to him for his reminding when I can't remember the noun for the moment. I am also very grateful for his guidance when I think about the problem and his final warning to me. Let me deeply understand my own shortcomings.
I'll come back.