当前位置:网站首页>Personal imitation SSM framework
Personal imitation SSM framework
2022-07-07 05:54:00 【Qingcheng】
Personal imitation SSM frame
1、Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wnx.mall.tiny</groupId>
<artifactId>web-my-ssm</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>web-my-ssm</name>
<description> Personal imitation SSM frame </description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!--thymeleaf-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.14.RELEASE</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
<!-- Reflection can get the real method name -->
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
2、Spring The configuration file
Put in resources\applicationContext.xml
<?xml version="1.0" encoding="utf-8"?>
<beans>
<bean id="pmsBrandMapper" class="com.wnx.mall.tiny.mapper.impl.PmsBrandMapperImpl"/>
<bean id="PmsBrandService" class="com.wnx.mall.tiny.service.impl.PmsBrandServiceImpl">
<property name="pmsBrandMapper" ref="pmsBrandMapper"/>
</bean>
<bean id="brand" class="com.wnx.mall.tiny.controller.PmsBrandController">
<property name="fruitService" ref="fruitService"/>
</bean>
</beans>
3、Web.xml To configure
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
<!-- Configure context parameters -->
<context-param>
<param-name>view-prefix</param-name>
<param-value>/</param-value>
</context-param>d
<context-param>
<param-name>view-suffix</param-name>
<param-value>.html</param-value>
</context-param>
<!--Spring The location of the configuration file -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>applicationContext.xml</param-value>
</context-param>
</web-app>
4、 Context load listener ContextLoaderListener
be responsible for Create... When the context starts IOC Containers , Then save it to application Scope
package com.wnx.myssm.mylistner;
import com.wnx.myssm.myioc.BeanFactory;
import com.wnx.myssm.myioc.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/** * Context load listener */
@WebListener
public class ContextLoaderListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
//1. Create... When the context starts IOC Containers , Then save it to application Scope
ServletContext application = sce.getServletContext();
String path = application.getInitParameter("contextConfigLocation");
BeanFactory beanFactory = new ClassPathXmlApplicationContext(path);
application.setAttribute("beanFactory",beanFactory);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
5、 Front controller DispatcherServlet
package com.wnx.myssm.mysrpingmvc;
import com.wnx.myssm.myioc.BeanFactory;
import com.wnx.myssm.utils.StringUtil;
import lombok.SneakyThrows;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
/** * all *.do Your request will enter the Servlet!!! */
@WebServlet("*.do")
public class DispatcherServlet extends ViewBaseServlet {
private BeanFactory beanFactory ;
public DispatcherServlet(){
}
public void init() throws ServletException {
//1.Servlet At the bottom of the build, you will call Init() Method , Integrate ViewBaseServlet, Going to call ViewBaseServlet Of Init()
super.init();
//2. from application Scope to get IOC Containers
ServletContext application = getServletContext();
Object beanFactoryObj = application.getAttribute("beanFactory");
if(beanFactoryObj!=null){
beanFactory = (BeanFactory)beanFactoryObj ;
}else{
throw new RuntimeException("IOC Container acquisition failed !");
}
}
@SneakyThrows
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. obtain Bean ID
String servletPath = request.getServletPath();
servletPath = servletPath.substring(1);
int lastDotIndex = servletPath.lastIndexOf(".do") ;
servletPath = servletPath.substring(0,lastDotIndex);
//2. according to ID Take out of the container Bean
Object controllerBeanObj = beanFactory.getBean(servletPath);
//3. Get method name
String operate = request.getParameter("operate");
if(StringUtil.isEmpty(operate)){
operate = "index" ; }
Method[] methods = controllerBeanObj.getClass().getDeclaredMethods();
for (Method method : methods) {
//4. obtain Handler Method object
if (operate.equals(method.getName())) {
Parameter[] parameters = method.getParameters();
Object[] parameterValues = new Object[parameters.length];
//5. complete Controller Method parameter binding
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
String parameterName = parameter.getName();
if ("request".equals(parameterName)) {
parameterValues[i] = request;
} else if ("response".equals(parameterName)) {
parameterValues[i] = response;
} else if ("session".equals(parameterName)) {
parameterValues[i] = request.getSession();
} else {
String parameterValue = request.getParameter(parameterName);
String typeName = parameter.getType().getName();
Object parameterObj = parameterValue;
if (parameterObj != null) {
if ("java.lang.Integer".equals(typeName)) {
parameterObj = Integer.parseInt(parameterValue);
}
}
if (parameterObj != null) {
if ("java.lang.Long".equals(typeName)) {
parameterObj = Long.parseLong(parameterValue);
}
}
parameterValues[i] = parameterObj;
}
}
//6. Reflection execution method
method.setAccessible(true);
Object returnObj = method.invoke(controllerBeanObj, parameterValues);
//7. The view
String methodReturnStr = (String) returnObj;
if (methodReturnStr.startsWith("redirect:")) {
String redirectStr = methodReturnStr.substring("redirect:".length());
response.sendRedirect(redirectStr);
} else {
super.processTemplate(methodReturnStr, request, response);
}
}
}
}
}
6、 view resolver ViewBaseServlet
package com.wnx.myssm.mysrpingmvc;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ViewBaseServlet extends HttpServlet {
private TemplateEngine templateEngine;
@Override
public void init() throws ServletException {
// 1. obtain ServletContext object
ServletContext servletContext = this.getServletContext();
// 2. establish Thymeleaf Parser object
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
// 3. Set parameters to the parser object
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setPrefix(servletContext.getInitParameter("view-prefix"));
templateResolver.setSuffix(servletContext.getInitParameter("view-suffix"));
templateResolver.setCacheTTLMs(60000L);
templateResolver.setCacheable(true);
templateResolver.setCharacterEncoding("utf-8");
// 4. Create template engine object
templateEngine = new TemplateEngine();
// 5. Set the template parser for the template engine object
templateEngine.setTemplateResolver(templateResolver);
}
protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 1. Set the content type and character set of the response body
resp.setContentType("text/html;charset=UTF-8");
// 2. establish WebContext object
WebContext webContext = new WebContext(req, resp, getServletContext());
// 3. Process template data
templateEngine.process(templateName, webContext, resp.getWriter());
}
}
7、IOC Container context ClassPathXmlApplicationContext
- abstract Bean factory
package com.wnx.myssm.myioc;
/** * Bean Build factory */
public interface BeanFactory {
Object getBean(String id);
}
- Realization :ClassPathXmlApplicationContext
package com.wnx.myssm.myioc;
import com.wnx.myssm.utils.StringUtil;
import lombok.SneakyThrows;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String,Object> beanMap = new HashMap<>();
@SneakyThrows
public ClassPathXmlApplicationContext(){
this("applicationContext.xml");
}
@SneakyThrows
public ClassPathXmlApplicationContext(String path){
if(StringUtil.isEmpty(path)){
throw new RuntimeException("IOC The container's configuration file does not specify ..."); }
//1. according to Resource Under the table of contents applicationContext.xml, Construct document objects
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(path);
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder() ;
Document document = documentBuilder.parse(inputStream);
//2. Scan all Bean label
NodeList beanNodeList = document.getElementsByTagName("bean");
for(int i = 0 ; i<beanNodeList.getLength() ; i++){
Node beanNode = beanNodeList.item(i);
if(beanNode.getNodeType() == Node.ELEMENT_NODE){
//1. according to Bean label , Construct objects from reflections
Element beanElement = (Element)beanNode ;
String beanId = beanElement.getAttribute("id");
String className = beanElement.getAttribute("class");
Class beanClass = Class.forName(className);
Object beanObj = beanClass.newInstance() ;
//2. Deposit in Map Containers
beanMap.put(beanId , beanObj) ;
}
}
//3. assemble bean Dependencies between
for(int i = 0 ; i<beanNodeList.getLength() ; i++){
Node beanNode = beanNodeList.item(i);
if(beanNode.getNodeType() == Node.ELEMENT_NODE) {
Element beanElement = (Element) beanNode;
String beanId = beanElement.getAttribute("id");
NodeList beanChildNodeList = beanElement.getChildNodes();
for (int j = 0; j < beanChildNodeList.getLength() ; j++) {
//4. Take the dependent from the container Bean Inject into the dependent Bean in
Node beanChildNode = beanChildNodeList.item(j);
if(beanChildNode.getNodeType()==Node.ELEMENT_NODE && "property".equals(beanChildNode.getNodeName())){
Element propertyElement = (Element) beanChildNode;
String propertyName = propertyElement.getAttribute("name");
String propertyRef = propertyElement.getAttribute("ref");
Object refObj = beanMap.get(propertyRef);
Object beanObj = beanMap.get(beanId);
Class beanClazz = beanObj.getClass();
Field propertyField = beanClazz.getDeclaredField(propertyName);
propertyField.setAccessible(true);
propertyField.set(beanObj,refObj);
}
}
}
}
}
/** * according to ID obtain Bean * @param id ID * @return Bean */
@Override
public Object getBean(String id) {
return beanMap.get(id);
}
}
8、 Configure character encoding filter
package com.wnx.myssm.myfilter;
import com.wnx.myssm.utils.StringUtil;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/** * Character encoding filter Filter *.do Request */
@WebFilter(urlPatterns = {
"*.do"},initParams = {
@WebInitParam(name = "encoding",value = "UTF-8")})
public class CharacterEncodingFilter implements Filter {
private String encoding = "UTF-8";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String encodingStr = filterConfig.getInitParameter("encoding");
if(StringUtil.isNotEmpty(encodingStr)){
encoding = encodingStr ;
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
((HttpServletRequest)servletRequest).setCharacterEncoding(encoding);
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
9、 Persistence layer frame BaseMapper
package com.wnx.mall.tiny.mapper;
import com.wnx.myssm.mymapper.ConnUtil;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public abstract class BaseMapper<T> {
private final String DRIVER = "com.mysql.cj.jdbc.Driver";
private final String URL = "jdbc:mysql://localhost:3306/mall?useUnicode=true&characterEncoding=utf-8&useSSL=false";
private final String USER = "root";
private final String PWD = "root" ;
private Connection conn ;
private PreparedStatement psmt ;
private ResultSet rs ;
private Class entityClass ;
public BaseMapper(){
//1. Get program runtime ,T The type of actual reference .
Type genericType = getClass().getGenericSuperclass();
Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments();
Type actualType = actualTypeArguments[0];
// 2. Construct the T Class object of
try {
entityClass = Class.forName(actualType.getTypeName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/** * Get database connection * @return A database connection */
private Connection getConn(){
return ConnUtil.getConn();
}
/** * Release database related resources * @param rs Result set object * @param psmt Precompiled statement object * @param conn Database connection */
private void close(ResultSet rs, PreparedStatement psmt, Connection conn){
try {
if (rs != null) {
rs.close();
}
if(psmt!=null){
psmt.close();
}
if(conn!=null && !conn.isClosed()){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/*** * Placeholders for preprocessing statement objects ? Set parameters * @param psmt Preprocess the statement object * @param params Parameters * @throws SQLException SQL abnormal */
private void setParams(PreparedStatement psmt , Object... params) throws SQLException {
if(params!=null && params.length>0){
for (int i = 0; i < params.length; i++) {
psmt.setObject(i+1,params[i]);
}
}
}
/*** * Perform database update operation * @param sql Database operation SQL * @param params Update parameters * @return Rows affected */
protected int executeUpdate(String sql , Object... params){
boolean insertFlag = false ;
try {
conn = getConn();
psmt = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
setParams(psmt,params);
int count = psmt.executeUpdate() ;
rs = psmt.getGeneratedKeys();
if(rs.next()){
return ((Long)rs.getLong(1)).intValue();
}
return count ;
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(rs,psmt,conn);
}
return 0;
}
/** * Give... By reflection technology obj Object's property Attribute propertyValue value * @param obj object model * @param property model Field * @param propertyValue model value */
private void setValue(Object obj , String property , Object propertyValue){
//1. Get the class of the object
Class clazz = obj.getClass();
try {
//2. Get the member variable according to the member variable name
Field field = clazz.getDeclaredField(property);
//3. Reflection assignment
if(field!=null){
field.setAccessible(true);
field.set(obj,propertyValue);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/** * Execute complex queries , Returns, for example, statistical results * @param sql Database operation SQL * @param params Update parameters * @return An array of objects */
protected Object[] executeComplexQuery(String sql , Object... params){
try {
//1. Execute the query
conn = getConn() ;
psmt = conn.prepareStatement(sql);
setParams(psmt,params);
rs = psmt.executeQuery();
//2. Construct column containers
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
Object[] columnValueArr = new Object[columnCount];
//3. The query results are put into the column container
if(rs.next()){
for(int i = 0 ; i<columnCount;i++){
Object columnValue = rs.getObject(i+1);
columnValueArr[i]=columnValue;
}
//4. Return column container
return columnValueArr ;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rs,psmt,conn);
}
return null ;
}
/** * Execute the query , Returns a single entity object * @param sql Database operation SQL * @param params Query parameters * @return Entity Model */
protected T load(String sql , Object... params){
try {
//1. Query operation
conn = getConn() ;
psmt = conn.prepareStatement(sql);
setParams(psmt,params);
rs = psmt.executeQuery();
//2. Object Assignment
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
if(rs.next()){
T entity = (T)entityClass.newInstance();
for(int i = 0 ; i<columnCount;i++){
String columnName = rsmd.getColumnName(i+1);
//3. The transformation of hump naming
while (columnName.contains("_")) {
int index = columnName.indexOf("_");
String target = columnName.substring(index + 1, index + 2);
columnName = columnName.replace(("_" + target), target.toUpperCase());
}
Object columnValue = rs.getObject(i+1);
setValue(entity,columnName,columnValue);
}
//3. Returns the object
return entity ;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close(rs,psmt,conn);
}
return null ;
}
/*** * Execute the query , return List * @param sql Database operation SQL * @param params Query parameters * @return Set of entities List */
protected List<T> executeQuery(String sql , Object... params){
List<T> list = new ArrayList<>();
try {
//1. Execute the query
conn = getConn() ;
psmt = conn.prepareStatement(sql);
setParams(psmt,params);
rs = psmt.executeQuery();
//2. Object Assignment
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
while(rs.next()){
T entity = (T)entityClass.newInstance();
for(int i = 0 ; i<columnCount;i++){
String columnName = rsmd.getColumnName(i+1);
//3. The transformation of hump naming
while (columnName.contains("_")) {
int index = columnName.indexOf("_");
String target = columnName.substring(index + 1, index + 2);
columnName = columnName.replace(("_" + target), target.toUpperCase());
}
Object columnValue = rs.getObject(i+1);
setValue(entity,columnName,columnValue);
}
//4. Add to collection
list.add(entity);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close(rs,psmt,conn);
}
//5. Back to the assembly
return list ;
}
}
10、 Transaction control TransactionManager
package com.wnx.myssm.mytransaction;
import com.wnx.myssm.mymapper.ConnUtil;
import java.sql.Connection;
import java.sql.SQLException;
public class TransactionManager {
// Open transaction
public static void beginTrans() throws SQLException {
ConnUtil.getConn().setAutoCommit(false);
}
// Commit transaction
public static void commit() throws SQLException {
Connection conn = ConnUtil.getConn();
conn.commit();
ConnUtil.closeConn();
}
// Roll back the transaction
public static void rollback() throws SQLException {
Connection conn = ConnUtil.getConn();
conn.rollback();
ConnUtil.closeConn();
}
}
11、 Thread knowledge
Use a connection Connection To say things , One request corresponds to one thread . Rewrite the get database connection class
- ConnUtil
package com.wnx.myssm.mymapper;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnUtil {
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/javaweb?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true";
private static final String USER = "root";
private static final String PWD = "root";
/** * Create database connection * @return Back to database connection */
private static Connection createConn() {
try {
Class.forName(DRIVER);
return DriverManager.getConnection(URL, USER, PWD);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return null;
}
/** * Get database connection * @return Database connection */
public static Connection getConn() {
//1. If there is a connection with a local thread , Create a .
Connection conn = threadLocal.get();
if (conn == null) {
conn = createConn();
threadLocal.set(conn);
}
return threadLocal.get();
}
/** * Close database connection * @throws SQLException SQL abnormal */
public static void closeConn() throws SQLException {
Connection conn = threadLocal.get();
if(conn==null){
return ;
}
if(!conn.isClosed()){
conn.close();
threadLocal.set(null);
}
}
}
Once something goes wrong , Let the current database connection rollback immediately .
- OpenSessionInViewFilter
package com.wnx.myssm.myfilter;
import com.wnx.myssm.mytransaction.TransactionManager;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.sql.SQLException;
@WebFilter("*.do")
public class OpenSessionInViewFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
try{
TransactionManager.beginTrans();
System.out.println(" Open transaction ....");
filterChain.doFilter(servletRequest, servletResponse);
TransactionManager.commit();
System.out.println(" Commit transaction ...");
}catch (Exception e){
e.printStackTrace();
try {
TransactionManager.rollback();
System.out.println(" Roll back the transaction ....");
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
@Override
public void destroy() {
}
}
边栏推荐
- 谈fpga和asic的区别
- Web Authentication API兼容版本信息
- make makefile cmake qmake都是什么,有什么区别?
- Distributed global ID generation scheme
- 【已解决】记一次EasyExcel的报错【读取xls文件时全表读不报错,指定sheet名读取报错】
- zabbix_ Get test database failed
- 盘点国内有哪些EDA公司?
- linear regression
- Flink SQL realizes reading and writing redis and dynamically generates hset key
- Paper reading [semantic tag enlarged xlnv model for video captioning]
猜你喜欢
随机推荐
关于服装ERP,你知道多少?
zabbix_get测试数据库失败
WEB架构设计过程
Modes of optical fiber - single mode and multimode
AI人脸编辑让Lena微笑
数据中心为什么需要一套基础设施可视化管理系统
2pc of distributed transaction solution
[cloud native] what is the microservice architecture?
Wechat applet Bluetooth connects hardware devices and communicates. Applet Bluetooth automatically reconnects due to abnormal distance. JS realizes CRC check bit
Go 語言的 Context 詳解
Message queuing: how to ensure that messages are not lost
Distributed global ID generation scheme
cf:C. Column Swapping【排序 + 模拟】
软件测试面试技巧
How to get free traffic in pinduoduo new store and what links need to be optimized in order to effectively improve the free traffic in the store
Bbox regression loss function in target detection -l2, smooth L1, IOU, giou, Diou, ciou, focal eiou, alpha IOU, Siou
Nvisual network visualization
980. 不同路径 III DFS
English grammar_ Noun possessive
Type de texte de commutation d'entrée et de mot de passe de l'applet natif








