Mvc进阶(下)

news2024/11/26 2:34:57

Mvc进阶(下)

  • 1.前言
  • 2.上次代码弊端
    • 1.利用xml建模反射优化
      • 1.XMl文件
      • 2.对xml建模
    • 3.修改中央控制器
  • 3.再优化
    • 1.先优化Action子控制器
    • 4.优化传值问题
  • 4.总结

在这里插入图片描述

1.前言

虽然前面文章深入解析Java自定义MVC框架的原理与实现讲述了Mvc框架,但是那只能算是比较低级的,还能够再优化,接下来我会再优化3次代码,让代码更为简洁,通用。

2.上次代码弊端

虽然简化了代码,但是代码并不 能够通用,MVC这种东西,最终是要打包成jar架包的,可是上一篇文章的代码优化并不能够打包成架包,现在开始第一次优化。

1.利用xml建模反射优化

1.XMl文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE config
[<!ELEMENT config (action*)>

<!ELEMENT action (forward*)>
<!ATTLIST action 
path CDATA #REQUIRED

type CDATA #IMPLIED
>

]
>



	<!--
		config标签:可以包含0~N个action标签
	-->
	
	
<config>
	<!--
		action标签:可以饱含0~N个forward标签 path:以/开头的字符串,并且值必须唯一 非空 ,子控制器对应的路径
		type:字符串,非空,子控制器的完整类名
	-->
	<action path="/book" type="com.niyin.com.BookAction">
		<forward name="list" path="/res.jsp" redirect="true" />
		<forward name="tolist" path="/res.jsp" redirect="false" />
	</action>
	
	<action path="/order" type="com.niyin.com.Orderaction">
		<forward name="success" path="/index.jsp" redirect="true" />
		<forward name="failed" path="/register.jsp" redirect="false" />
	</action>
	
	<action path="/bookAction" type="test.BookAction">
		<forward name="add" path="/bookAdd.jsp" redirect="true" />
		<forward name="del" path="/reg.jsp" redirect="false" />
		<forward name="list" path="/list.jsp" redirect="false" />
		<forward name="upd" path="/login.jsp" redirect="false" />
	</action>
	
	<action path="/loginAction" type="test.action.LoginAction">
		<forward name="a" path="/index.jsp" redirect="false" />
		<forward name="b" path="/welcome.jsp" redirect="true" />
	</action>
</config>




2.对xml建模

package model;

import java.util.HashMap;
import java.util.Map;

public class ActionModel {
	private String path;
	private String type;
	private Map<String ,ForwardModel>fmp=new HashMap<String ,ForwardModel>();
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	
	public void push(ForwardModel forwardModel) {
		fmp.put(forwardModel.getName(), forwardModel);
		  
	}
	public  ForwardModel pop(String name) {
		
		
		return fmp.get(name);
		
	}
	

}

package model;

import java.util.HashMap;
import java.util.Map;

public class ConfigModel {
private Map<String,ActionModel>aMap=new HashMap<String,ActionModel>();



public void push(ActionModel actionModel) {
	
	aMap.put(actionModel.getPath(), actionModel);

}
public ActionModel pop(String path) {
	
	return aMap.get(path);
	
}
public static void main(String[] args) throws Exception {
	ConfigModel configModel =new ConfigMOdelFactory().build();
	ActionModel actionModel=configModel.pop("/loginAction");
	
	ForwardModel forwardModel =actionModel.pop("b");
	System.out.println(forwardModel.getPath());
}

}

package model;

import java.io.InputStream;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class ConfigMOdelFactory {

	public static ConfigModel build() throws Exception {
		ConfigModel configModel = new ConfigModel();

		InputStream in = ConfigMOdelFactory.class.getResourceAsStream("/config.xml");
		SAXReader sr = new SAXReader();
		Document doc = sr.read(in);
		List<Element> actionsEles = doc.selectNodes("/config/action");
		for (Element element : actionsEles) {
			// System.out.println(element.asXML());

			ActionModel actionmodel = new ActionModel();
			actionmodel.setPath(element.attributeValue("path"));
			actionmodel.setType(element.attributeValue("type"));

			List<Element> forwardEles = element.selectNodes("forward");
			for (Element forwardEle : forwardEles) {

				// System.out.println(forwardEle.asXML());
				ForwardModel forwardModel = new ForwardModel();
				forwardModel.setName(forwardEle.attributeValue("name"));
				forwardModel.setPath(forwardEle.attributeValue("path"));
				forwardModel.setRedirect(!"false".equals(forwardEle.attributeValue("redirect")));
				actionmodel.push(forwardModel);
			}
			configModel.push(actionmodel);
		}
		return configModel;

	}

	public static void main(String[] args) throws Exception {
		ConfigMOdelFactory.build();
	}
}

package model;

import java.util.HashMap;
import java.util.Map;

public class ForwardModel {

	private String name;
	private String path;
	private boolean redirect;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public boolean isRedirect() {
		return redirect;
	}
	public void setRedirect(boolean redirect) {
		this.redirect = redirect;
	}
	
	
}

3.修改中央控制器

以前把所有的子控制器放到map集合中,现在所有的子控制器再config。xml中。

package com.niyin.framework;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;

import com.niyin.com.BookAction;
import com.niyin.com.Orderaction;

import model.ActionModel;
import model.ConfigMOdelFactory;
import model.ConfigModel;
import model.ForwardModel;

@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {
	
	private ConfigModel configMOdel;
//	public Map<String, Action> actionMap=new HashMap<String, Action>();
	
		
		
	@Override
	public void init() throws ServletException {
//	actionMap.put("/book", new BookAction());
//	actionMap.put("/order", new Orderaction());
//	actionMap.put("/cat", new CatAction());
		try {
			configMOdel=ConfigMOdelFactory.build();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	this.doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	String uri = request.getRequestURI();	
			
	uri=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
//	Action action = actionMap.get(uri);
//	要通过uri=book/再configMOdel中找
	ActionModel actionModel = configMOdel.pop(uri);
	if (actionModel==null)
		throw new RuntimeException("action 没有配置");
	
 String type = actionModel.getType();
		Action action;
		try {
			action = (Action) Class.forName(type).newInstance();
			

		
	
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 

	
	
	
	}

}

把map集合取消,改为用模型的方式来代替map集合,如果要新增类的话只需要新增模型对象即可,不用再加入map集合中,让代码更易于维护和修改,也可以封装架包提供了可行性。

代码测试


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<p>版本1</p>
<a href="Bookservletadd">增加</a>
<a href="Bookservletupd">修改</a>
<a href="Bookservletdel">减少</a>
<a href="Bookservletlist">查询</a>


<p>版本2</p>
<a href="Bookservletadd?methodName=add">增加</a>
<a href="Bookservletupd?methodName=upd">修改</a>
<a href="Bookservletdel?methodName=del">减少</a>
<a href="Bookservletlist?methodName=list">查询</a>
<p>版本3</p>
<a href="Bookservletadd?methodName=add">增加</a>
<a href="Bookservletupd?methodName=upd">修改</a>
<a href="Bookservletdel?methodName=del">减少</a>
<a href="Bookservletlist?methodName=list">查询</a>
<p>版本4</p>
<a href="book.action?methodName=add">增加</a>
<a href="book.action?methodName=upd">修改</a>
<a href="book.action?methodName=del">减少</a>
<a href="book.action?methodName=list">查询</a>

版本4的弊端:中央控制器的action容器加载,不可以灵活配置

<p>版本五</p>
<a href="order.action?methodName=add">增加</a>
<a href="order.action?methodName=upd">修改</a>
<a href="order.action?methodName=del">减少</a>
<a href="order.action?methodName=list">查询</a>
</body>
</html>

在这里插入图片描述
控制台输出
在这里插入图片描述

3.再优化

虽然上面代码优化后可以灵活配置了,但是使用重定向和转发有问题,查询必然转发,增删改使用重定向,如果频繁刷新页面,可能会出现重复提交数据。

1.先优化Action子控制器

package com.niyin.framework;

import java.io.IOException;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Action {
	protected String excute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String methoed = request.getParameter("methodName");
//	private
		String res="";
		try {
			Method m = this.getClass().getDeclaredMethod(methoed, HttpServletRequest.class,HttpServletResponse.class);
			m.setAccessible(true);
			res=(String) m.invoke(this, request,response);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return res;
	}	
}

把book里面的类型也改为String,并返回tolist,和list,通过返回值来判断它是需要重定向还是转发,并且还节约了代码。

package com.niyin.com;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.niyin.entity.Book;
import com.niyin.framework.Action;
import com.niyin.framework.ModelDrivern;

public class BookAction extends Action implements ModelDrivern<Book> {
private Book book=new Book();

	private String list(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("list");
//		response.sendRedirect("res.jsp");
		request.setAttribute("content", "你就会");
//		request.getRequestDispatcher("res.jsp").forward(request, response);
	return "list";
	}
	private String del(HttpServletRequest request, HttpServletResponse response) throws Exception {
	// TODO Auto-generated method stub
	System.out.println("del");
//	response.sendRedirect("res.jsp");
	request.setAttribute("content", "你就会");
	return "tolist";


}

private String upd(HttpServletRequest request, HttpServletResponse response) throws Exception {
	// TODO Auto-generated method stub
	System.out.println("upd");
//	response.sendRedirect("res.jsp");

	request.setAttribute("content", "你就会");
	return "tolist";

}

private String add(HttpServletRequest request, HttpServletResponse response) throws IOException {
	// TODO Auto-generated method stub
	System.out.println("add");
//	response.sendRedirect("res.jsp");
	request.setAttribute("content", "你就会");

	return "tolist";

}
@Override
public Book getModel() {
	System.out.println(book);
	
	return book;
}

}

优化中央控制器,通过模型对象获取·forward对象来判断该重定向还是转发。

package com.niyin.framework;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;

import com.niyin.com.BookAction;
import com.niyin.com.Orderaction;

import model.ActionModel;
import model.ConfigMOdelFactory;
import model.ConfigModel;
import model.ForwardModel;

@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {
	
	private ConfigModel configMOdel;
//	public Map<String, Action> actionMap=new HashMap<String, Action>();
	
		
		
	@Override
	public void init() throws ServletException {
//	actionMap.put("/book", new BookAction());
//	actionMap.put("/order", new Orderaction());
//	actionMap.put("/cat", new CatAction());
		try {
			configMOdel=ConfigMOdelFactory.build();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	this.doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	String uri = request.getRequestURI();	
			
	uri=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
//	Action action = actionMap.get(uri);
//	要通过uri=book/再configMOdel中找
	ActionModel actionModel = configMOdel.pop(uri);
	
	      String res= action.excute(request, response);
	      
ForwardModel forwardModel = actionModel.pop(res);
	if (forwardModel!=null) {

		boolean redirect = forwardModel.isRedirect();
		String path = forwardModel.getPath();
	if (redirect) {
		response.sendRedirect(request.getContextPath()+path);
	}else {
		request.getRequestDispatcher(path).forward(request, response);
	}
	} 
		
	
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 

	
	
	
	}

}

运行结果
在这里插入图片描述
结果是一样的说明优化成功。

4.优化传值问题

一般来说通过servlet拿到前端的值再把它传入数据库,这个过程要写很多重复代码,现在来优化一下,利用反射等等
1.先定义一个模型驱动接口

package com.niyin.framework;

/**
 * 
 * @author 匿瘾
 *
 * @param <T>
 * 模型驱动接口
 */
public interface ModelDrivern<T> {
T getModel();
	
	
}

2.让bookaction实现这个接口

package com.niyin.com;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.niyin.entity.Book;
import com.niyin.framework.Action;
import com.niyin.framework.ModelDrivern;

public class BookAction extends Action implements ModelDrivern<Book> {
private Book book=new Book();

	private String list(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("list");
//		response.sendRedirect("res.jsp");
		request.setAttribute("content", "你就会");
//		request.getRequestDispatcher("res.jsp").forward(request, response);
	return "list";
	}
	private String del(HttpServletRequest request, HttpServletResponse response) throws Exception {
	// TODO Auto-generated method stub
	System.out.println("del");
//	response.sendRedirect("res.jsp");
	request.setAttribute("content", "你就会");
	return "tolist";


}

private String upd(HttpServletRequest request, HttpServletResponse response) throws Exception {
	// TODO Auto-generated method stub
	System.out.println("upd");
//	response.sendRedirect("res.jsp");

	request.setAttribute("content", "你就会");
	return "tolist";

}

private String add(HttpServletRequest request, HttpServletResponse response) throws IOException {
	// TODO Auto-generated method stub
	System.out.println("add");
//	response.sendRedirect("res.jsp");
	request.setAttribute("content", "你就会");

	return "tolist";

}
@Override
public Book getModel() {
	System.out.println(book);
	
	return book;
}

}

3.优化中央控制器

在控制器内判断有没有实现接口,如果实现了就把值传进去。

package com.niyin.framework;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;

import com.niyin.com.BookAction;
import com.niyin.com.Orderaction;

import model.ActionModel;
import model.ConfigMOdelFactory;
import model.ConfigModel;
import model.ForwardModel;

@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {
	
	private ConfigModel configMOdel;
//	public Map<String, Action> actionMap=new HashMap<String, Action>();
	
		
		
	@Override
	public void init() throws ServletException {
//	actionMap.put("/book", new BookAction());
//	actionMap.put("/order", new Orderaction());
//	actionMap.put("/cat", new CatAction());
		try {
			configMOdel=ConfigMOdelFactory.build();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	this.doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	String uri = request.getRequestURI();	
			
	uri=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
//	Action action = actionMap.get(uri);
//	要通过uri=book/再configMOdel中找
	ActionModel actionModel = configMOdel.pop(uri);
	if (actionModel==null)
		throw new RuntimeException("action 没有配置");
	
 String type = actionModel.getType();
		Action action;
		try {
			action = (Action) Class.forName(type).newInstance();
			
//			bookaction 有没有实现这个接口
			if (action instanceof ModelDrivern) {
				ModelDrivern md=(ModelDrivern) action;
				Object bean = md.getModel();
				Map<String, String[]> map = request.getParameterMap();
				BeanUtils.populate(bean, map);
//				把值封进去
				
			}
	      String res= action.excute(request, response);
	      
ForwardModel forwardModel = actionModel.pop(res);
	if (forwardModel!=null) {

		boolean redirect = forwardModel.isRedirect();
		String path = forwardModel.getPath();
	if (redirect) {
		response.sendRedirect(request.getContextPath()+path);
	}else {
		request.getRequestDispatcher(path).forward(request, response);
	}
	} 
		
	
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 

	
	
	
	}

}

最后通过degbug查看book里面是否有值判断是否成功的,传入了值。
结果:
在这里插入图片描述
可以看到book里面是有值的,所以最后一个优化也成功了。

4.总结

通过建模xml和反射的方式优化代码,让代码以Mvc框架的形式出现,
MVC框架构思巧妙。让代码更为简洁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/720751.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

suse ha for sap scale-up性能优化场景安装配置

1. 安装SUSE操作系统 在官网下载SUSE Linux Enterprise Server for SAP Applications安装介质&#xff0c;在安装操作系统过程中&#xff0c;选择SUSE Linux Enterprise Server for SAP Applications操作系统。 在软件选择界面&#xff0c;根据需要选择SAP HANA Server Base…

oracle connect by很强,但是要慎用,不然有你哭的时候

前言: 第四次工业革命&#xff0c;带来了科技的巨大变更&#xff0c;同时带来了很多半结构化数据&#xff0c;很多数据会做成集合、JSON的形式存储到数据库中&#xff0c;通过ETL工具我们将这些数据抽取到数仓里面&#xff0c;我们怎么进行分析呢&#xff1f;这些数据类似这样的…

centos7安装git及maven

安装git 直接使用yum安装&#xff0c;指令如下&#xff1a; yum install git然后执行如下指令判断是否安装完成&#xff1a; git --version紧接着需要维护git的用户名及邮箱等信息 git config --global user.name "zzy" git config --global user.email "ex…

JS知识点汇总(十四)--事件循环

1. 对事件循环的理解 JavaScript 在设计之初便是单线程&#xff0c;即指程序运行时&#xff0c;只有一个线程存在&#xff0c;同一时间只能做一件事 JavaScript 初期作为一门浏览器脚本语言&#xff0c;通常用于操作 DOM &#xff0c;如果是多线程&#xff0c;一个线程进行了删…

QT学习笔记:调整控件大小和位置

前面的文章&#xff0c;我讲了怎么用layout去布局。但布局做完后&#xff0c;发现界面有点怪。比如&#xff0c;最低下的“清除”按钮这么大&#xff0c;“消息体”这个label没有位于中间等。下面&#xff0c;我就来讲下怎么把界面继续优化。 1、调整“清除”按钮大小和位置 …

第八步:STM32F4 EXTI

1.0 外部中断概述 STM32F4的每个IO都可以作为外部中断输入。 STM32F4的中断控制器支持22个外部中断/事件请求&#xff1a; EXTI线0~15&#xff1a;对应外部IO口的输入中断。 EXTI线16&#xff1a;连接到PVD输出。 EXTI线17&#xff1a;连接到RTC闹钟事件。 EXTI线18&#xff1…

Kubernetes(k8s)实战:Kubernetes(k8s)部署Springboot项目

文章目录 一、练手&#xff1a;k8s部署部署wordpressmysql1、创建wordpress命名空间2、创建mysql数据库3、创建wordpress应用4、小结 二、实战&#xff1a;部署自己的springboot项目1、准备一个springboot项目2、使用docker打成镜像3、使用k8s部署springboot 三、实战&#xff…

pycharm配置虚拟环境

pychram配置虚拟环境&#xff0c;然后使终端在该目录下 win键r 输入cmd, 进入dos命令。使用conda create -n cleanRobot python3.7 创建cleanRobot虚拟环境。 输入&#xff1a; conda activate cleanRobot 进行虚拟环境激活。 我们在安装的anaconda的目录下可以看到刚刚建…

Java批量操作Excel文件实践

摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 | 问题背景 在操作Excel的场景中&#xff0c;通常会有一些针对Excel的批量操作&…

基于matlab使用Grad-CAM探索语义分割网络(附源码)

一、前言 此示例演示如何使用 Grad-CAM 探索预训练语义分割网络的预测。 语义分割网络对图像中的每个像素进行分类&#xff0c;从而生成按类分割的图像。您可以使用深度学习可视化技术 Grad-CAM 来查看图像的哪些区域对像素分类决策很重要。 二、下载预训练网络 从剑桥大学…

基于Java工贸学生信息管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

vscode多主题色功能实现机制

vscode的页面分为两部分&#xff0c;一部分是插件提供&#xff0c;一部分是主体。那么vscode在多主题实现上就要考虑把这两部分结合起来管理&#xff0c;相对来说要比单纯的网页实现多主题功能要复杂一些。 主体部分实现 我们先看下vscode主体部分样式是如何画出来了 registe…

Spring系列2 -- Spring的创建和使用

Spring 就是⼀个包含了众多工具方法的 IOC容器。既然是容器那么它就具备两个最基本的功能&#xff1a; 将对象存储到容器&#xff08;Spring&#xff09;中&#xff1b;从容器中将对象取出来。 在Java中对象也叫做Bean&#xff0c;后续我们就把对象称之为Bean&#xff1b; 目录…

数据结构--二叉树的定义和基本术语

数据结构–二叉树的定义和基本术语 二叉树的基本概念 二叉树是 n ( n ≥ 0 &#xff09; n (n\ge0&#xff09; n(n≥0&#xff09;个结点的有限集合: ①或者为 空二叉树 \color{red}空二叉树 空二叉树&#xff0c;即n 0。 ②或者由一个 根结点 \color{red}根结点 根结点和两…

ModaHub魔搭社区:腾讯发布的向量数据库Tencent Cloud VectorDB有哪些核心能力?

腾讯发布的向量数据库有哪些核心能力&#xff1f; 腾讯云刚刚发布的向量数据库Tencent Cloud VectorDB主要具备以下能力&#xff1a; 高性能向量存储、检索&#xff1a;腾讯云向量数据库具备高性能的向量存储和检索能力&#xff0c;单索引能够轻松支持10亿级别的向量规模。在…

十二、flex练习

需求&#xff1a;做出下面的样式 代码实现&#xff1a; <body><ul class"nav"><li><a href"#">HTML/CSS</a></li><li><a href"#">Browser Side</a></li><li><a href&q…

【Hello mysql】 数据库库操作

Mysql专栏&#xff1a;Mysql 本篇博客简介&#xff1a;介绍数据库的库操作 库的操作 创建数据库创建数据库案例字符集和校验规则查看系统默认字符集和校验规则查看数据库支持的字符集和校验规则 校验规则对于数据库的影响操纵数据库查看数据库显示创建语句修改数据库数据库删除…

【7月新刊】避雷!这4本期刊竟无影响因子?!7月期刊目录已更新 (多本期刊影响因子上涨)~

6月28日&#xff0c;科睿唯安发布了最新JCR报告&#xff0c;一时间几家欢喜几家愁&#xff0c;但有的作者却发现&#xff0c;自己投稿的期刊虽然被核心库收录却没有影响因子&#xff0c;不免慌了神。 总的来说&#xff0c;被核心库收录的期刊没有公布影响因子&#xff0c;一般…

实战干货,自动化测试框架mark标记详细实战,进阶高级测试...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 pytest可以支持对…

键盘输入一个字符 a’,串口工具显示“b 实现现象:键盘输入一个字符串,串口工具回显输入的字符串

1.键盘输入一个字符 a’,串口工具显示"b 2.实现现象:键盘输入一个字符串&#xff0c;串口工具回显输入的字符串 uart4.h #ifndef __UART4__H__ #define __UART4__H__ #include "stm32mp1xx_uart.h" #include "stm32mp1xx_gpio.h" #include "st…