Servlet执行流程生命周期方法介绍体系结构、Request和Response的功能详解

news2025/1/11 8:16:08

在这里插入图片描述

🐌个人主页: 🐌 叶落闲庭
💨我的专栏:💨
c语言
数据结构
javaEE
操作系统
Redis

石可破也,而不可夺坚;丹可磨也,而不可夺赤。


Servlet

  • 一、 Servlet执行流程
  • 二、Servlet生命周期
  • 三、 Servlet方法介绍
  • 四、 Servlet体系结构
  • 五、 urlPattern配置
  • 六、 XML配置Servlet(老版本)
  • 七、Request
    • 7.1 Request继承体系
    • 7.2 Request获取请求数据
    • 7.3 Request通用方式获取请求参数
    • 7.4 请求参数中文乱码处理
      • 7.4.1 POST 解决方案
      • 7.4.1 GET 解决方案
    • 7.5 Request请求转发
  • 八、Response
    • 8.1 设置相应数据功能
    • 8.2 完成重定向
    • 8.3资源路径问题
    • 8.4 Response响应字符数据
    • 8.5 Response响应字节数据

一、 Servlet执行流程

  • Servlet由Tomcat服务器创建,,web项目发布到Tomcat服务器后,Tomcat服务器会自动调用web项目中的service()方法,但是在调用service()方法之前,会先创建一个Servlet对象,这个Servlet对象也是由Tomcat服务器创建的,Servlet执行流程就是由浏览器向Servlet发送请求,根据url路径找到要执行的方法,也就是service()方法,这个service()方法也是Tomcat调用的,这个service()方法一被调用,就会返回对应的响应给客户端浏览器。

在这里插入图片描述


二、Servlet生命周期

  • 对象的生命周期指一个对象从被创建到被销毁的整个过程
  • Servleti运行在Servlet:容器(web服务器)中,其生命周期由容器来管理,分为4个阶段:
    • 1.加载和实例化:默认情况下,当Servlet第一次被访问时,由容器创建Servlet对象
    • 2.初始化:在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作,该方法只调用一次
    • 3.请求处理:每次请求Servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理。
    • 4.服务终止:当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法完成资源的释放,在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收
@WebServlet("/demo")
public class ServletDemo implements Servlet {

    /**
     * 初始化方法
     * 1.调用时机:默认情况下,Servlet被第一次访问时调用
     * 2.调用次数:1次
     * @param servletConfig
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init...");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * 提供服务
     * 1.调用时机:每次Servlet被访问时调用
     * 2.调用次数:多次
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("hello service~");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    /**
     * 销毁方法
     * 1.调用时机:内存释放或服务器关闭时
     * 2.调用次数:1次
     */
    @Override
    public void destroy() {
        System.out.println("destroy...");
    }
}

在这里插入图片描述


三、 Servlet方法介绍

  • 初始化方法,在Servleti被创建时执行,只执行一次
void init(ServletConfig servletConfig)
  • 提供服务方法,每次Servleti被访问,都会调用该方法
void service(ServletRequest servletRequest, ServletResponse servletResponse)
  • 销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet
void destroy()
  • 获取ServletConfig对象
ServletConfig getServletConfig()
  • 获取Servlet信息
String getServletInfo()

@WebServlet("/demo")
public class ServletDemo implements Servlet {

    private ServletConfig servletConfig;

    /**
     * 初始化方法
     * 1.调用时机:默认情况下,Servlet被第一次访问时调用
     * 2.调用次数:1次
     * @param servletConfig
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        this.servletConfig = servletConfig;
        System.out.println("init...");
    }

    @Override
    public ServletConfig getServletConfig() {
        return this.servletConfig;
    }

    /**
     * 提供服务
     * 1.调用时机:每次Servlet被访问时调用
     * 2.调用次数:多次
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("hello service~");
    }

    @Override
    public String getServletInfo() {
        return "";
    }

    /**
     * 销毁方法
     * 1.调用时机:内存释放或服务器关闭时
     * 2.调用次数:1次
     */
    @Override
    public void destroy() {
        System.out.println("destroy...");
    }
}

四、 Servlet体系结构


在这里插入图片描述


  • 我们将来开发B/S架构的web项目,都是针对HTTP协议所以我们自定义Servlet,会继承HttpServlet
  • 自定义Servlet,重写doGetdoPost方法:
@WebServlet("/demo1")
public class ServletDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("post...");
    }
}

  • 默认执行doGet方法:

在这里插入图片描述


  • 执行doPost方法:
    • 创建一个html文件,定义一个表单,设置url路径,方法为post请求,发送post请求:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>doPost</title>
</head>
<body>
<form action="/BBS/demo1" method="post">
    <input name="username">
    <input type="submit">
</form>
</body>
</html>

在这里插入图片描述


五、 urlPattern配置

  • Servlet要想被访问,必须配置其访间路径(urlPattern)
  • 一个Servlet,可以配置多个urlPattern
 String[] urlPatterns() default {};
@WebServlet(urlPatterns = {"/demo1","/demo2"})
  • urlPattern配置规则
    • 精确匹配
      • 配置路径:@WebServlet(urlPatterns = "/user/select")
      • 访问路径:http://localhost:8080/BBS/user/select
    • 目录匹配
      • 配置路径:@WebServlet(urlPatterns = "/user/*")
      • 访问路径:http://localhost:8080/BBS/user/aaa(aaa可以使任意字符)
    • 扩展名匹配
      • 配置路径:@WebServlet(urlPatterns = "*.do")注意:此处没有/,这里的*表示任意以.do的路径均可
      • 访问路径:http://localhost:8080/BBS/demo1.do
    • 任意匹配
      • 配置路径:@WebServlet(urlPatterns = "/")@WebServlet(urlPatterns = "/*")后者优先级更高
      • 访问路径:http://localhost:8080/BBS/ /后可为任意内容
    • //*的区别:
      • 当我们的项目中的Servlet配置了"/”,会覆盖掉tomcat中的DefaultServlet,当其他的url-patterni都匹配不上时都会走这个Servlet
      • 当我们的项目中配置了“*”,意味着匹配任意访问路径
  • 优先级:
    • 精确路径 > 目录路径 > 扩展名路径 > /* > /

六、 XML配置Servlet(老版本)

  • 1.编写Servlet类
  • 2.在web.xml中配置该Servlet类
<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <!--Servlet全类名-->
  <servlet>
    <servlet-name>demo2</servlet-name>
    <servlet-class>test.ServletDemo2</servlet-class>
  </servlet>
  <!--Servlet访问路径-->
  <servlet-mapping>
    <servlet-name>demo2</servlet-name>
    <url-pattern>/demo2</url-pattern>
  </servlet-mapping>
</web-app>

七、Request

  • Request:获取请求数据
  • Response:设置响应数据

7.1 Request继承体系


在这里插入图片描述


  • Tomcati需要解析请求数据,封装为request对象并且创建request对象传递到service方法中
  • 使用request对象,查阅JavaEE API文档的HttpServletRequest接口

7.2 Request获取请求数据

  • 请求行:
  • GET /request-demo/req1?username=zhangsan HTTP/1.1
    • String getMethod():获取请求方式:GET
    • String getContextPath():获取虚拟目录(项目访问路径):/request-demo
    • String Buffer getRequestURL():获取URL(统一资源定位符):http:/localhost:8080/request–demo/req1
    • String getRequestURI():获取URI(统一资源标识符):/request-demo/req1
    • String getQueryString():获取请求参数(GET方式):username=zhangsan&password=123
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //String getMethod()
        String method = req.getMethod();
        System.out.println(method);
        //String getContextPath()
        String contextPath = req.getContextPath();
        System.out.println(contextPath);
        //String Buffer getRequestURL()
        StringBuffer requestURL = req.getRequestURL();
        System.out.println(requestURL.toString());
        //String getRequestURI()
        String requestURI = req.getRequestURI();
        System.out.println(requestURI);
        //String getQueryString()
        String queryString = req.getQueryString();
        System.out.println(queryString);
    }

在这里插入图片描述


  • 请求头:
  • User-Agent:Mozilla/5.0 Chrome/91.0.4472.106
  • String getHeader((String name); 根据请求头名称,获取值
//user-agent:浏览器版本信息
String agent = req.getHeader("user-agent");
System.out.println(agent);

在这里插入图片描述


  • 请求体:
  • username=superbaby&password=123
  • ServletInputStream getInputStream();获取字节输入流
  • BufferedReader getReader();获取字符输入流
@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取字符输入流
        BufferedReader reader = req.getReader();
        //2.读取数据
        String s = reader.readLine();
        System.out.println(s);
    }

在这里插入图片描述


7.3 Request通用方式获取请求参数

  • Map<String,String[]>getParameterMap():获取所有参数Map集合

  • String[]getParameterValues(String name):根据名称获取参数值(数组)

  • String getParameter(String name):根据名称获取参数值(单个值)

  • get方式:

    • html代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>doPost</title>
</head>
<body>
<form action="/BBS/demo5" method="get">
    <input type="text" name="username"><br>
    <input type="password" name="password"><br>
    <input type="checkbox" name="hobby" value="1"> 游泳
    <input type="checkbox" name="hobby" value="2"> 跑步 <br>
    <input type="submit">
</form>
</body>
</html>
  • Java代码:
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //Get请求
        System.out.println("get...");
        //1.获取所有参数的Map集合
        Map<String, String[]> parameterMap = req.getParameterMap();
        for (String key : parameterMap.keySet()) {
            System.out.print(key + ": ");
            //获取值
            String[] strings = parameterMap.get(key);
            for (String string : strings) {
                System.out.print(string + " ");
            }
            System.out.println();
        }
        System.out.println("----------------------");
        //2.根据key获取值
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        System.out.println("----------------------");
        //3.获取单个参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
    }
  • post方式:
    • html代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>doPost</title>
</head>
<body>
<form action="/BBS/demo5" method="post">
    <input type="text" name="username"><br>
    <input type="password" name="password"><br>
    <input type="checkbox" name="hobby" value="1"> 游泳
    <input type="checkbox" name="hobby" value="2"> 跑步 <br>
    <input type="submit">
</form>
</body>
</html>
  • Java代码:
@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //Post请求
        System.out.println("get...");
        //1.获取所有参数的Map集合
        Map<String, String[]> parameterMap = req.getParameterMap();
        for (String key : parameterMap.keySet()) {
            System.out.print(key + ": ");
            //获取值
            String[] strings = parameterMap.get(key);
            for (String string : strings) {
                System.out.print(string + " ");
            }
            System.out.println();
        }
        System.out.println("----------------------");
        //2.根据key获取值
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        System.out.println("----------------------");
        //3.获取单个参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
    }
  • 通用代码:
@WebServlet("/demo5")
public class ServletDemo5 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //Get请求
        System.out.println("get...");
        //1.获取所有参数的Map集合
        Map<String, String[]> parameterMap = req.getParameterMap();
        for (String key : parameterMap.keySet()) {
            System.out.print(key + ": ");
            //获取值
            String[] strings = parameterMap.get(key);
            for (String string : strings) {
                System.out.print(string + " ");
            }
            System.out.println();
        }
        System.out.println("----------------------");
        //2.根据key获取值
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        System.out.println("----------------------");
        //3.获取单个参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

7.4 请求参数中文乱码处理

7.4.1 POST 解决方案

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码POST
        //设置字符输入流的编码
        req.setCharacterEncoding("utf-8");
        //获取数据
        String username = req.getParameter("username");
        System.out.println(username);
    }

7.4.1 GET 解决方案

  • GET获取参数方式:getQueryString
  • 产生乱码的原因:
    • 浏览器在解析中文字符时采用UTF-8的字符集通过URL进行编码,将中文转换成%+16进制数的格式,然后将转换后的字符发送给服务器进行解码,tomcat在进行解码时是通过ISO-8859-1的字符集进行URL解码,由于编码和解码时用的字符集不同,所以就会出现乱码。
  • URL编码:
    • 将字符串按照编码方式转为二进制
    • 每个字节转为2个16进制数并在前边加上%
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码GET
        String username = req.getParameter("username");
        //转换为字节数据,编码
        byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
        //将字节数组转换为字符串,解码
        username = new String(bytes,"utf-8");
        System.out.println(username);
    }
  • Tomcat8.0之后,已将GET请求乱码问题解决,设置默认的解码方式为UTF-8

7.5 Request请求转发

  • 请求转发(forward):一种在服务器内部的资源跳转方式
req.getRequestDispatcher("资源B路径").forward(req,resp);
  • 请求转发资源间共享数据:使用Request对象
  • void setAttribute(String name,Object o):存储数据到request域中
  • Object getAttribute(String name):根据key,获取值
  • void removeAttribute(String name):根据key,删除该键值对
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("demo7...");
        //存储数据
        req.setAttribute("msg","hello");
        //请求转发
        req.getRequestDispatcher("/demo8").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

@WebServlet("/demo8")
public class ServletDemo8 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("demo8...");
        //获取数据
        Object msg = req.getAttribute("msg");
        System.out.println(msg);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
  • 请求转发特点:
    • 浏览器地址栏路径不发生变化
    • 只能转发到当前服务器的内部资源
    • 一次请求,可以在转发的资源间使用request共享数据

八、Response

8.1 设置相应数据功能

  • 响应数据分为3部分:
    • 响应行
      • 设置响应状态码:
void setStatus(int sc)
    • 响应头
      • 设置响应键值对
void setHeader(String name,String value)
    • 响应体
      • 获取字符输出流
PrintWriter getWriter();
      • 获取字节输出流
ServletOutputStream getOutputStream();

8.2 完成重定向

  • 重定向(Redirect):一种资源跳转方式
@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("resp1...");
        //重定向
        //设置响应状态码302
        //resp.setStatus(302);
        //设置响应头
        //resp.setHeader("Location","/BBS/resp2");
        //简化方式
        resp.sendRedirect("/BBS/resp2");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
@WebServlet("/resp2")
public class ResponseDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("resp2...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
  • 重定向特点:
    • 浏览器地址栏路径发生变化
    • 可以重定向到任意位置的资源(服务器内部、外部均可)
    • 两次请求,不能在多个资源使用request:共享数据

8.3资源路径问题

  • 明确路径谁使用?
    • 浏览器使用:需要加虚拟目录(项目访问路径)
    • 服务端使用:不需要加虚拟目录
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("resp1...");
        //简化方式
        //动态获取虚拟目录
        String contextPath = req.getContextPath();
        resp.sendRedirect(contextPath + "/resp2");
    }

8.4 Response响应字符数据

  • 使用:
    • 1.通过Response对象获取字符输出流
PrintWriter writer resp.getWriter();
  • 2.写数据
writer.write("hello~");

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        resp.setHeader("content-type","text/html");
        writer.write("<h1>hello~</h1>");
        writer.write("<h1>你好~</h1>");
    }

注意:

  • 该流不需要关闭,随着响应结束,response对象销毁,由服务器关闭
  • 中文数据乱码:原因通过Response获取的字符输出流默认编码:ISO-8859-1

8.5 Response响应字节数据

  • 使用:
  • 通过Response对象获取字符输出流
ServletOutputStream outputStream resp.getOutputStream();
  • 写数据
outputStream.write("字节数据")

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //读取文件
        FileInputStream fis = new FileInputStream("d://head.jpg");
        //获取response字节输出流
        ServletOutputStream os = resp.getOutputStream();
        //完成流的copy
        byte[] buff = new byte[1024];
        int len = 0;
        while ((len = fis.read(buff)) != -1) {
            os.write(buff,0,len);
        }
        fis.close();
    }
  • IOUtils工具类使用:
    • 导入坐标:
<dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.6</version>
</dependency>
    • 使用:
IOUtils.copy(fis,os);

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //读取文件
        FileInputStream fis = new FileInputStream("d://head.jpg");
        //获取response字节输出流
        ServletOutputStream os = resp.getOutputStream();
        //完成流的copy
        IOUtils.copy(fis,os);
        fis.close();
    }

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

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

相关文章

【Java】Stream的基本使用

Stream特点 Stream的一系列操作组成了Stream的流水线, Stream流水线包含: 数据源: 这里的数据源可能是集合/数组, 可能是生成器, 甚至可能是IO通道(Files.lines)零个或多个中间操作: 中间操作会导致流之间的转化, 如filter(Predicate)一个终端操作: 终端操作会产生最终所需要的…

德国自动驾驶卡车公司【Fernride】完成1900万美元A轮融资

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于德国沃尔夫斯堡的自动驾驶卡车公司【Fernride】今日宣布已完成1900万美元A轮融资&#xff0c;本轮融资完成后Fernride的融资金额已经达到了达到5000万美元。 本轮融资由Deep Tech and Cli…

初步了解nodejs语法和web模块

在此&#xff0c; 第一个Node.js实例_js firstnode-CSDN博客 通过node运行一个简单的server.js&#xff0c;实现了一个http服务器&#xff1b; 但是还没有解析server.js的代码&#xff0c;下面看一下&#xff1b; require 指令 在 Node.js 中&#xff0c;使用 require 指令来…

MySQL-基础

MySQL 1.SQL语句 1.1数据库 -- 创建数据库 create database review character set 字符集 create database if not exists review charset 字符集 collate 比较规则 -- 查看表的创建细节 show create database review -- 修改数据库 alter database review charset utf8mb4 …

Springboot——关于Springboot线程池时使用ThreadLocal 类的一个小小的漏洞

问题描述 前端的使用ajax发送了一个请求到后端 后端自定义了一个线程上下文和实现了一个拦截器Interceptor public class BaseContext {public static ThreadLocal<Integer> threadLocal new ThreadLocal<>();public static void setCurrentId(int id) {threadL…

javaWeb医疗管理系统

一、引言 1.1 系统背景 医疗行业一直是一个高度复杂和信息密集的领域。现代医院需要有效管理患者信息、医生信息、药物信息以及医疗记录等。本项目旨在通过开发一个JavaWeb医疗管理系统来满足这些需求。 1.2 目的和范围 这个系统的主要目标是帮助医院提高患者管理和医疗记录…

竞赛 机器视觉opencv答题卡识别系统

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 答题卡识别系统 - opencv python 图像识别 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分…

解决u盘在我的电脑中重复显示两个

删除注册表&#xff1a; [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\DelegateFolders\{F5FB2C77-0E2F-4A16-A381-3E560C68BC83}]

800*B. Long Long(贪心)

解析&#xff1a; 因为可以无限操作&#xff0c;所以最大值即为全部数字的绝对值&#xff0c;次数为连续负数区间的个数。 #include<bits/stdc.h> using namespace std; #define int long long const int N2e55; int t,n,a[N]; signed main(){scanf("%lld",&a…

力扣-367.有效的完全平方数

暴力 class Solution { public:bool isPerfectSquare(int num) {for(long i 1; i * i < num; i) {if(i * i num) return true;}return false;} };二分查找 class Solution { public:bool isPerfectSquare(int num) {int left 1, right num;while(left < right) {in…

Linux用户和权限

目录 1、root用户&#xff08;超级管理员&#xff09; su和exit命令 sudo命令 2、用户和用户组管理 用户组管理 用户管理 getent命令 3、查看权限控制信息 4、修改权限控制&#xff1a;chmod命令 5、修改权限控制&#xff1a;chown命令 1、root用户&#xff08;超级管…

Django之十三、添加用户之原始方法实现

修改urls.py path("user/add/", views.user_add),添加user_add.html {% extends layout.html %} {% block content %}<div class"container"><div class"panel panel-default"><div class"panel-heading"><h3 c…

AAD基础知识(identity/token/PRT)

简介 AAD(Azure Active Directory/Azure AD)是微软基于云身份验证和访问控制的解决方案&#xff0c;通过SSO登录其他o365应用(word/outlook/teams…) 微软在2023年7月把AAD重命名为Microsoft Entra ID&#xff0c;官网&#xff1a;https://www.microsoft.com/zh-cn/security/b…

LabVIEW开发带式谱感测技术

LabVIEW开发带式谱感测技术 如今&#xff0c;通过无线网络传输的数据量正在迅速增加&#xff0c;并导致频谱稀缺。超过数十亿的无线设备将被连接起来&#xff0c;并需要互联网接入。因此&#xff0c;无线电频谱管理方案的效率不足以授予对所有设备的访问权限。在频谱分配中&am…

深入学习JUC,深入了解Java线程中死锁与活锁问题,并理解其解决方法,笔记开记!!!

文章目录 死锁检查是否发生了死锁死锁的概念死锁产生的条件预防死锁解决死锁 活锁概念解决 ReentrantLock概念可重入可打断可超时可设置公平锁条件变量 死锁 检查是否发生了死锁 jstack通过 线程栈快照 定位线程中出现长时间停顿的原因, jconsole 图像界面 检查是否发生了死锁…

redis中list类型的操作

一、特点 Redis列表是简单的字符串列表&#xff0c;按照插入顺序排序。你可以添加一个元素到列表的头部&#xff08;左边&#xff09;或者尾部&#xff08;右边&#xff09;。一个列表最多可以包含 2^32 - 1 个元素 (超过40亿个元素)。 list其底层使用quicklist存储数据 qu…

mysql面试题10:MySQL中有哪几种锁?表级锁、行级锁、页面锁区别和联系?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:Mysql中有哪几种锁? 在MySQL中,主要有以下几种类型的锁: 共享锁(Shared Lock):也称为读锁。多个事务可以同时持有共享锁,可以读取但不能修…

想要精通算法和SQL的成长之路 - 验证二叉树的前序序列化

想要精通算法和SQL的成长之路 - 验证二叉树的前序序列化 前言一. 验证二叉树的前序序列化 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 验证二叉树的前序序列化 原题链接 思路&#xff08;参考负雪明图&#xff09;&#xff1a; 首先我们看题目所给的字符串&#xff…

Ipython和Jupyter Notebook介绍

Ipython和Jupyter Notebook介绍 Python、IPython和Jupyter Notebook是三个不同但密切相关的工具。简而言之&#xff0c;Python是编程语言本身&#xff0c;IPython是对Python的增强版本&#xff0c;而Jupyter Notebook是一种在Web上进行交互式计算的环境&#xff0c;使用IPytho…

CSS学习小结

css的两种使用方式&#xff1a; ①内嵌样式表 ②导入外部样式表&#xff08;实际开发常用&#xff09;<link href"...." rel"stylesheet"/> 选择器&#xff1a; ①标签选择器&#xff1a;通过标签种类决定 ②类选择器&#xff1a;class"..…