学习Java的日子 Day61 Listener监听器

news2024/9/23 5:26:18

Day61 Listener监听器

JavaWeb 三大组件(Servlet、Filter、Listener)

概念

监听器用于监听web应用中某些对象信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。

常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等。

监听器可以监听就是在 applicationsessionrequest 三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件。

applicationServletContext 类型的对象,ServletContext 代表整个web应用,在服务器启动的时候,tomcat会自动创建该对象。在服务器关闭时会自动销毁该对象。

创建步骤

1.创建类

2.实现指定的监听器接口中的方法

3.在web.xml文件中配置监听/在类上标注@WebListener 注解

JavaEE的监听器:

在这里插入图片描述

没有这个pageContext:上下文对象

1.第一大类监听器:监听请求对象的创建和销毁

监听域对象 创建与销毁的监听器

需要导包,servlet-api.jar

监听器接口描述
ServletRequestListener监听请求对象的创建、销毁
HttpSessionListener监听会话对象的创建、销毁
ServletContextListener监听全局域对象的创建、销毁

1.1 ServletRequestListener

请求对象的生命周期:

​ 创建:客户端发送请求,Tomcat会创建请求对象(请求对象可以存储数据,但是时间很短,在项目中要跳转时,需要临时数据,就存储在请求对象中)

​ 销毁:服务器返回响应,Tomcat会将请求对象销毁

MyServletRequestListener

package com.qf.listener01;

public class MyServletRequestListener implements ServletRequestListener {

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {

        //获取请求对象
        ServletRequest request = servletRequestEvent.getServletRequest();
        System.out.println("请求对象被创建了"+request);
    }
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {

        //获取请求对象
        ServletRequest request = servletRequestEvent.getServletRequest();
        System.out.println("请求对象被销毁了"+request);
    }


}

web.xml

也可以使用@WebListener注解

<listener>
	<listener-class>com.qf.listener01.MyServletRequestListener</listener-class>
</listener>

Welcome.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h1>Welcome.html</h1>

</body>
</html>

page01.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>page01.jsp</h1>
</body>
</html>

运行结果:

在这里插入图片描述

1.2 HttpSessionListener

监听会话域对象的创建和销毁

会话对象的生命周期:

​ 创建:服务端使用到会话对象才会被创建

​ 销毁:会话域对象过期时间到后会被销毁

注意:

1.客户端访问服务器里的html页面不会创建会话对象,因为没有使用到session

2.客户端访问服务器里的jsp页面会创建会话对象,因为使jsp里9大内置对象里有session

3.会话域对象过期时间默认30分钟

4.在web.xml中可以设置session的过期时间(时间单位:分钟),注意:最后一次使用session的时间往后移(闲置时间)

<session-config>
	<session-timeout>60</session-timeout>
</session-config>

经验:

session对象在服务器中存储,默认30分钟过期时间

JSESSIONID存储在客户端的Cookie中,默认过期时间是会话结束时

这样会导致,关闭客户端后,session对象还存活在服务端,相同的客户端再次开启并发送请求访问session时就会创建新的session对象,原有的session对象就视作为占用资源的无效对象

我们可以设置JSESSIONID的过期时间(和session对象的过期时间一致),用户关闭客户端再次开启后才能找到之前在服务器对应的session对象

package com.qf.listener01;

@WebListener
public class MyHttpSessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        System.out.println("会话域对象被创建了:" + session.getId());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {

        HttpSession session = httpSessionEvent.getSession();
        System.out.println("会话域对象被销毁了:" + session.getId());
    }
}

运行结果:
在这里插入图片描述

Welcome.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <h1>welcome.html</h1>
    <a href="ser01">向Servlet01发送请求</a>

</body>
</html>

客户端访问servlet会不会创建session对象?

不会,只有servlet里面使用request.getSession()时,才会创建

工作流程:

1.向Tomcat获取当前客户端的session对象

2.Tomcat会获取请求里参数(cookie)的JSESSIONID

​ 3.1 请求里参数中没有JSESSIONID,说明客户端在服务器中没有对应的session对象,就创建

​ 3.2 请求里参数中有JSESSIONID,Tomcat通过JSESSIONID获取容器里的session对象

​ 3.2.1 有可能没有获取到,就创建新的session对象(服务器里的session对象过期时间到了被销毁了,但是客户端Cookie里的JSESSIONID还没过期)

​ 3.2.2 获取到,就直接取出使用

4.返回响应,响应参数里会携带JSESSIONID,为了客户端下次发送请求时还能找到之前的session对象

package com.qf.servlet;

@WebServlet("/ser01")
public class Servlet01 extends HttpServlet {

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

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

        HttpSession session = request.getSession();
        String id = session.getId();
        System.out.println("Servlet01接收到请求了..." + id);

        //设置JSESSIONID的过期时间(和session对象的过期时间一致)
        Cookie cookie = new Cookie("JSESSIONID", id);
        cookie.setMaxAge(60*30);
        response.addCookie(cookie);

    }
}

1.3 ServletContextListener

第一大类监听器:监听全局域对象创建和销毁

全局域对象的生命周期:

​ 创建:项目启动时

​ 销毁:服务器正常关闭时

经验:让整个项目共享的数据可以存储在全局域对象里

初始化数据存储在全局域对象中

package com.qf.listener01;

@WebListener
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {

        ServletContext servletContext = servletContextEvent.getServletContext();
        
        //获取全局域对象的初始化参数 -- 注意:在web.xml中配置
        String code = servletContext.getInitParameter("code");
        System.out.println("全局域对象被创建了:" + servletContext + " -- " + code);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

        ServletContext servletContext = servletContextEvent.getServletContext();
        System.out.println("全局域对象被销毁了:" + servletContext );
        
        //服务器在停止的时候,要执行某些动作,那么就可以把代码写在这个位置!!!	
    }
}


运行结果:

在这里插入图片描述

1.4 案例:统计网站在线人数

MyServletContextListener

package com.qf.listener01;

@WebListener
public class MyServletContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {

        ServletContext servletContext = servletContextEvent.getServletContext();

        //设置网站在线人数
        //项目启动,向application对象中存一个变量,初始值0
        servletContext.setAttribute("count",0);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    
    }
}

MyHttpSessionListener

package com.qf.listener01;

@WebListener
public class MyHttpSessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {

        // 有人访问了 count++
        //获取全局域对象
        ServletContext servletContext = session.getServletContext();
        //更新网站在线人数
        int count = (Integer) servletContext.getAttribute("count");
        count++;
        servletContext.setAttribute("count",count);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();

        
        // 有人离开了 count--
        ServletContext servletContext = session.getServletContext();
        int count = (Integer) servletContext.getAttribute("count");
        count--;
        servletContext.setAttribute("count",count);
    }
}

2.第二类:属性监听器(了解)

监听域对象属性变化的监听器

监听器接口描述
ServletContextAttributeListener监听Servlet上下文对象属性的创建、删除、替换
HttpSessionAttributeListener监听会话对象属性的创建、删除、替换
ServletRequestAttributeListener监听请求对象属性的创建、删除、替换

2.1 ServletRequestAttributeListener

第二大类监听器:监听请求域对象属性的添加、删除、替换

package com.qf.listener02;

@WebListener
public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        ServletRequest request = servletRequestAttributeEvent.getServletRequest();
        String name = servletRequestAttributeEvent.getName();
        Object value = servletRequestAttributeEvent.getValue();
        System.out.println(request + "请求中的属性添加了:" + name + " -- " + value);
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {

        ServletRequest request = servletRequestAttributeEvent.getServletRequest();
        String name = servletRequestAttributeEvent.getName();
        Object value = servletRequestAttributeEvent.getValue();
        System.out.println(request + "请求中的属性删除了:" + name + " -- " + value);
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {

        ServletRequest request = servletRequestAttributeEvent.getServletRequest();
        String name = servletRequestAttributeEvent.getName();
        Object value = servletRequestAttributeEvent.getValue();//获取的被替换的value
        System.out.println(request + "请求中的属性替换了:" + name + " -- " + value);
    }
}

page01.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>page01.jsp</h1>

<%
    request.setAttribute("msg","aaa");//添加属性
    request.setAttribute("msg","bbb");//替换属性
    request.removeAttribute("msg");//删除属性
%>

</body>
</html>

在这里插入图片描述

2.2 HttpSessionAttributeListener

第二大类监听器:监听会话对象属性的添加、删除、替换

package com.qf.listener02;

@WebListener
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        HttpSession session = httpSessionBindingEvent.getSession();
        String name = httpSessionBindingEvent.getName();
        Object value = httpSessionBindingEvent.getValue();
        System.out.println(session.getId() + "会话中的属性添加了:" + name + " -- " + value);
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {

        HttpSession session = httpSessionBindingEvent.getSession();
        String name = httpSessionBindingEvent.getName();
        Object value = httpSessionBindingEvent.getValue();
        System.out.println(session.getId() + "会话中的属性删除了:" + name + " -- " + value);
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {

        HttpSession session = httpSessionBindingEvent.getSession();
        String name = httpSessionBindingEvent.getName();
        Object value = httpSessionBindingEvent.getValue();
        System.out.println(session.getId() + "会话中的属性替换了:" + name + " -- " + value);
    }
}

page01.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>page01.jsp</h1>

<%

    session.setAttribute("msg","aaa");//添加属性
    session.setAttribute("msg","bbb");//替换属性
    session.removeAttribute("msg");//删除属性
%>

</body>
</html>

在这里插入图片描述

2.3 ServletContextAttributeListener

第二大类监听器:全局域对象属性的添加、删除、替换

package com.qf.listener02;

@WebListener
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
    //Servlet上下文对象新增值的时候被调用
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {

        ServletContext servletContext = servletContextAttributeEvent.getServletContext();
        String name = servletContextAttributeEvent.getName();
        Object value = servletContextAttributeEvent.getValue();
        System.out.println(servletContext + "全局域中的属性添加了:" + name + " -- " + value);
    }

    //Servlet上下文对象删除值的时候被调用
    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {

        ServletContext servletContext = servletContextAttributeEvent.getServletContext();
        String name = servletContextAttributeEvent.getName();
        Object value = servletContextAttributeEvent.getValue();
        System.out.println(servletContext + "全局域中的属性删除了:" + name + " -- " + value);
    }

    //Servlet上下文对象替换值的时候被调用
    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {

        ServletContext servletContext = servletContextAttributeEvent.getServletContext();
        String name = servletContextAttributeEvent.getName();
        Object value = servletContextAttributeEvent.getValue();
        System.out.println(servletContext + "全局域中的属性替换了:" + name + " -- " + value);
    }
}

page01.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>page01.jsp</h1>

    <%
        //操作全局域对象的属性
        application.setAttribute("msg","aaa");//添加属性
        application.setAttribute("msg","bbb");//替换属性
        application.removeAttribute("msg");//删除属性
    %>

</body>
</html>

3.第三类:监听HttpSession中的对象(JavaBean)重要

前两类监听器是作用在 ServletContext HttpSession ServletRequest上

第三类监听器是作用在JavaBean上的

监听器接口描述
HttpSessionBindingListener监听会话对象中JavaBean对象的绑定、删除
HttpSessionActivationListener监听会话对象中JavaBean对象的钝化、活化

request对象存储时间短的数据

Session存储长期的数据

在这里插入图片描述

监听session里面的value中的user对象的变化,第一、第二类都不能精准定位

3.1 第三大类监听器:HttpSessionBindingListener

理解:监听该类(User)对象在session中的绑定(添加)和解绑(删除)

​ valueBound – 绑定方法

​ valueUnbound – 解绑方法

package com.qf.listener03;

public class User implements HttpSessionBindingListener{

    private String username;
    private transient String password;
    private String name;

    //无参构造,有参构造,get,set,toString()方法省略

    @Override
    public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {

        HttpSession session = httpSessionBindingEvent.getSession();
        String name = httpSessionBindingEvent.getName();
        Object value = httpSessionBindingEvent.getValue();

        System.out.println(session.getId() + "会话对象中绑定了:" + name + " -- " + value);
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
        HttpSession session = httpSessionBindingEvent.getSession();
        String name = httpSessionBindingEvent.getName();
        Object value = httpSessionBindingEvent.getValue();

        System.out.println(session.getId() + "会话对象中解绑了:" + name + " -- " + value);
    }

    @Override
    public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {

        HttpSession session = httpSessionEvent.getSession();
        System.out.println(session.getId() + "的User对象被钝化了:" + this);
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        System.out.println(session.getId() + "的User对象被活化了:" + this);
    }
}

3.2 第三大类监听器:HttpSessionActivationListener

理解:监听该类(User)对象在session中的钝化(序列化)和活化(反序列化)

sessionWillPassivate – 钝化(序列化):将类(User)对象写入到文件

sessionDidActivate – 活化(反序列化):将文件里的对象读取到程序中

  • 钝化:当服务器正常关闭时,还存活着的session对象(在设置时间内没有销毁) 会随着服务器的关闭被以文件(“SESSIONS.ser”)的形式存储(写入到)在tomcat 的work 目录下,这个过程叫做Session 的钝化
  • 活化:当服务器再次正常开启时,服务器会找到之前的“SESSIONS.ser” 文件,从中恢复之前保存起来的Session 对象,这个过程叫做Session的活化

注意:

实现session的钝化和活化底层使用到了ObjectInputStream、ObjectOutputStream

钝化和活化的JavaBean对象必须实现Serializable(序列化接口)

1.面试题:Session中的JavaBean对象什么情况下会钝化

​ session未过期

​ JavaBean对象所属的类必须实现Serializable接口

​ 服务器正常关闭

​ 以上三个条件必须都满足

2.面试题:Session中的JavaBean对象什么情况下不会钝化

​ 1.session对象过期

​ 2.session.invalidate();

​ 3.服务器非正常关闭

​ 以上三个条件满足一个即可

3.面试题:Session中的JavaBean对象什么情况下不会活化

​ 服务器启动,但是session对象过期了

注意事项

  1. 想要Session 被钝化、活化的对象它的类必须实现Serializable 接口,还要在服务器正常关闭的条件下,还未超时的Session 才会被钝化成文件。当Session 超时、调用invalidate方法或者服务器在非正常情况下关闭时,Session 都不会被钝化,因此也就不存在活化。
  2. 在被钝化成“SESSIONS.ser” 文件时,不会因为超过Session 过期时间而消失,这个文件会一直存在,等到下一次服务器开启时消失。
  3. 当多个Session 被钝化时,这些被钝化的Session 都被保存在一个文件中,并不会为每个Session 都建立一个文件。

在这里插入图片描述

package com.qf.listener03;

public class User implements HttpSessionActivationListener, Serializable {

    private String username;
    private transient String password;
    private String name;

    //无参构造,有参构造,get,set,toString()方法省略

    @Override
    public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {

        HttpSession session = httpSessionEvent.getSession();
        System.out.println(session.getId() + "的User对象被钝化了:" + this);
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        System.out.println(session.getId() + "的User对象被活化了:" + this);
    }
}

在WebContent\META-INF文件夹下创建一个context.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<Context>
	<!-- 
		maxIdleSwap:"1": session如果1分钟没有使用就序列化
		directory: 序列化后文件所保存的路径 
	-->
	<Manager className="org.apache.catalina.session.PersistentManager"
		maxIdleSwap="1">
		<Store className="org.apache.catalina.session.FileStore" 		
			directory="C:\\text" />
	</Manager>
</Context>	

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

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

相关文章

vue echarts 横向柱状图,交错正负轴标签

横向柱状图&#xff1a; 同一个页面展示多个相同横向柱状图&#xff1b; 代码如下&#xff1a; <template><div style"display: flex;justify-content: space-around;"><div v-for"(chart,index) in barChartList" :key"index"…

基于LoRA和AdaLoRA微调Qwen1.5-0.5B-Chat

本文只开放基于LoRA和AdaLoRA微调代码,具体技术可以自行学习。 Qwen1.5-0.5B-Chat权重路径:https://huggingface.co/Qwen/Qwen1.5-0.5B 数据集路径:https://github.com/DB-lost/self-llm/blob/master/dataset/huanhuan.json 1. 知识点 LoRA, AdaLoRA技术 具体技术可以去看…

Transformer 架构告诉我们什么?

欢迎来到雲闪世界。ChatGPT 等大型语言模型 (LLM) 的出色表现震惊了世界。这一突破源于 Transformer 架构的发明&#xff0c;该架构出奇地简单且可扩展。它仍然由深度学习神经网络构建。主要新增功能是所谓的“注意力”机制&#xff0c;该机制将每个单词标记置于语境中。此外&a…

睿考网:CPA考试各科难度分析

CPA考试分为专业阶段和综合阶段两个部分&#xff0c;其中专业阶段包含六个科目&#xff0c;六科难度分别为大家介绍一下。 《会计》科目是CPA专业阶段中基础且难度较低的科目&#xff0c;同时也是核心的科目。对于零基础的考生来说&#xff0c;可能会感到困难&#xff0c;需要…

【C语言】堆的实现

堆的基本概念 堆在逻辑上是完全二叉树&#xff0c;那什么又是完全二叉树呢&#xff1f; 完全二叉树简单来说就是前n-1层每个节点都有两个儿子&#xff0c;最后一层叶子紧挨着排列。 堆在物理结构上适合用数组存储。 让我们先来学习树->二叉树的基本知识&#xff08;可看文…

verilog中的$radom函数

我需要产生一个背压。背压每次经过x个时钟周期之后翻转&#xff0c;x是0到1_6000间的一个随机数。 如下图的代码&#xff0c;($random % 10)产生的是-9到9的数&#xff0c;包括0&#xff0c; ($random % 10) 1 那么值就在 -8到10之间。 always (posedge clk) beginDATA_READ…

K8S可视化管理平台KubeSphere

什么是 KubeSphere &#xff1f; KubeSphere 是一款开源项目&#xff0c;在目前主流容器调度平台 Kubernetes 之上构建的企业级分布式多租户容器管理平台&#xff0c;提供简单易用的操作界面以及向导式操作方式&#xff0c;在降低用户使用容器调度平台学习成本的同时&#xff…

DBeaver连接mysql时,报错Public Key Retrieval is not allowed

解决 在新建连接的时候&#xff0c;驱动属性里设置 allowPublicKeyRetrieval 的值为 true。

SQL进阶技巧:Hive URL解析函数详解及实际应用

目 录 0 实际业务需求 1 URL的基本组成 2 PROTOCOL 协议 3 Hive中的URL解析函数 3.1 数据准备 3.2 创建数据库 3.3 需求 3.3.1 parse_url 讲解 3.3.2 测试 3.3.3 实现需求 3.3.4 注意问题 3.5 parse_url_tuple 3.5.1 需求 3.5.2 实现需求 3.5.3 注意问题 4 小…

HTML + CSS 学习指南:从入门到精通

一、HTML CSS 简介 HTML 和 CSS 在网页开发中扮演着至关重要的角色。HTML 如同网页的骨架&#xff0c;为网页提供了基本的结构和内容。它使用各种标签来定义页面的元素&#xff0c;如标题、段落、图片、链接等&#xff0c;确保信息得以有条理地组织和呈现。 CSS 则恰似网页的…

点可云ERP进销存V8版本—购货退货单操作使用讲解

本章我们讲解购货退货单的使用场景及操作使用说明。 购货退货单是指供应商收回或退还给采购方的货物的单据。它记录了购货方向供应商退还货物的详细信息&#xff0c;一般会在货物质量问题、退货政策、错误订购等情况下发生购货退货。 购货退货单可以通过两个方式产生&#xff0…

学习记录——day24 多进程编程

创建三个进程 可以让父进程创建一个子进程&#xff0c;再由父进程或者子进程创建一个子进程 #include <myhead.h> int main(int argc, char const *argv[]) {pid_t pid fork();if (pid >0){//父进程pid_t pid1 fork();if (pid1 >0){printf("father\n"…

linux Ubuntu 安装mysql-8.0.39 二进制版本

我看到网上很多都写的乱七八糟, 我自己总结了一个 首先, 去Mysql官网上下载一个mysql-8.0.39二进制版本的安装包 这个你自己去下载我这里就写一个安装过程和遇到的坑 第一步 解压mysql压缩包和创建my.cnf文件 说明: 二进制安装指定版本MySQL的时候&#xff0c;需要手动写配置…

十月稻田玉米品类全国销量领先背后:“卖点”到“买点”的用户思维

近日&#xff0c;十月稻田在梯媒全新上线的新潮玉米广告&#xff0c;吸引了很多消费者的注意。 画面里&#xff0c;十月稻田的黄糯玉米棒金黄且饱满&#xff0c;旁白是广告语&#xff1a;“新玉米上市&#xff0c;香香香&#xff01;”。这支广告也挑起了许多观众的食欲&#…

【QGroundControl二次开发】七.QGC自定义MAVLink消息MavLink通信协议 C++应用

1. 接收解析源码分析 通过接收串口或UDP发来的的字节流buffer&#xff0c;长度lengthbuffer.size()&#xff0c;通过下列脚本解析&#xff0c;每解析出一个mavlink数据包就执行onMavLinkMessage函数 for(int i 0 ; i < length ; i){msgReceived mavlink_parse_char(MAVL…

【运维自动化】网络统一监控运维管理解决方案(PPT建设方案)

运维自动化是提升IT运维效率、降低人力成本、增强系统稳定性和可靠性的关键举措。随着业务规模的增长&#xff0c;传统的手动运维方式已难以满足快速响应和高效管理的需求。自动化运维通过脚本、工具和系统平台&#xff0c;实现日常任务自动化执行、故障预警与快速恢复、资源优…

数据结构笔记纸质总结

1.基本概念 2.复杂度 3.线性表 4.栈 5.队列 6.串 7.数组 8.矩阵 9.广义表 10.树

15.3 Zookeeper官方使用_实现分布式锁

1. 简介 2. 代码演示 2.1 客户端连接类 package com.ruoyi.common.zookeeper;import com.ruoyi.common.exception.UtilException; import

命途多舛的Concepts:从提出到剔除再到延期最后到纳入,Concepts为什么在C++中大起大落?

在C的漫长发展史中&#xff0c;Concepts&#xff08;概念&#xff09;的故事显得尤为引人注目。它的历程不仅是C社区技术演进的缩影&#xff0c;也是对软件工程实践的一次深刻反思。本文将详细剖析C的Concepts&#xff1a;它是什么&#xff0c;它的设计初衷与使用场景&#xff…

快手商业化 Java后端 二面|面试官很nice

面试总结&#xff1a;没有那种纯八股问题&#xff0c;都是偏向于情景题。看到面试官最后出了一道多叉树的题目&#xff0c;我以为是想直接刷人&#xff0c;但还是尽力去尝试了一下&#xff0c;最后也没做出来&#xff0c;面试官很nice&#xff0c;在答不上来的时候会引导我去思…