Listener监听器 | 监听域对象创建和销毁、使用监听器统计网站在线人数

news2024/12/23 7:57:04

目录 

一:监听域对象创建和销毁

1、什么是监听器?监听器有什么用?

2、Servlet规范中提供了哪些监听器?

3、实现一个监听器的步骤

4、HttpSessionBindingListener

5、HttpSessionIdListener & HttpSessionActivationListener

6、使用监听器统计网站在线人数


一:监听域对象创建和销毁

1、什么是监听器?监听器有什么用?

监听器是Servlet规范中的一员。就像Filter一样。Filter也是Servlet规范中的一员。

②在Servlet中,所有的监听器接口都是以“Listener”结尾

监听器实际上是Servlet规范留给我们javaweb程序员的特殊时机

④特殊的时刻如果想执行这段代码,你需要想到使用对应的监听器。

2、Servlet规范中提供了哪些监听器?

javax.servlet包下:

        ①ServletContextListener 

        ②ServletContextAttributeListener

        ③ServletRequestListener

        ④ServletRequestAttributeListener

jakarta.servlet.http包下:

        ①HttpSessionListener

        ②HttpSessionAttributeListener

        ③HttpSessionBindingListener

        ④HttpSessionIdListener

        ⑤HttpSessionActivationListener

3、实现一个监听器的步骤

这里主要先讲解熟悉的关于三个域对象的监听器:

ServletContext、ServletRequest、HttpSession

(1)以ServletContextListener为例

①第一步:编写一个类实现ServletContextListener接口。并且实现里面的方法。

监听器中的方法不需要程序员手动调用。是发生某个特殊事件之后被服务器调用。

// ServletContext对象被创建的时候调用。
void contextInitialized(ServletContextEvent event)
// ServletContext对象被销毁的时候调用
void contextDestroyed(ServletContextEvent event)

② 第二步:在web.xml文件中对ServletContextListener进行配置,如下:

当然,第二步也可以不使用配置文件,也可以用注解,例如:@WebListener 即可。

   <listener>
        <listener-class>com.bjpowernode.javaweb.servlet.MyServletContextListener</listener-class>
    </listener>

注意:所有监听器中的方法都是不需要javaweb程序员调用的,由服务器来负责调用。

什么时候被调用呢?当某个特殊的事件发生(特殊的事件发生其实就是某个时机到了)之后,被web服务器自动调用。

③服务器启动时,ServletContext对象创建, contextInitialized方法执行

    服务器关闭时,ServletContext对象销毁, contextDestroyed方法执行

package com.bjpowernode.javaweb.servlet;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.javaweb.servlet
 * @Project:JavaWeb
 * @name:MyServletContextListener
 * @Date:2022/12/4 13:23
 */
// ServletContextListener监听器主要监听的是:ServletContext对象的状态。
public class MyServletContextListener implements ServletContextListener { // 服务器启动时间点
    /**
     * 监听器中的方法不需要程序员手动调用。是发生某个特殊事件之后被服务器调用。
     * @param sce
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) { // 服务器关闭时间点
        // 现在这个特殊的时刻写代码,你写就是了。它会被服务器自动调用。
        // 这个方法是在ServletContext对象被创建的时候调用。
        System.out.println("ServletContext对象创建了。");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 现在这个特殊的时刻写代码,你写就是了。它会被服务器自动调用。
        // 这个方法是在ServletContext对象被销毁的时候调用。
        System.out.println("ServletContext对象被销毁了。");
    }
}

(2)以ServletRequestListener为例

④ServletRequest对象是一次请求创建一个request对象,所以服务器启动后:

只要发送一次请求就会调用requestInitialized方法,请求结束立刻会调用requestDestroyed

注:我们直接访问http://localhost:8080/servlet15/ 会报404错误,因为默认会访问index.html,但是我们并没有写;就算如此也会发送出请求,执行这个监听器。

package com.bjpowernode.javaweb.servlet;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;


/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.javaweb.servlet
 * @Project:JavaWeb
 * @name:MyServletRequestListener
 * @Date:2022/12/4 13:56
 */
@WebListener
public class MyServletRequestListener implements ServletRequestListener {
    // request对象销毁时间点
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("request对象销毁了");
    }

    // request对象创建时间点
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("request对象初始化了");
    }
}

(3)以HttpSessionListener为例

⑤我们都知道在访问jsp时,默认会创建session对象(九大内置对象);先编写一个my.jsp;在访问my.jsp时,会创建session对象,调用 sessionCreated方法;

当退出系统时,我们编写销毁session对象的方法,会调用sessionDestroyed方法。

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
my jsp page
<a href="${pageContext.request.contextPath}/exit">退出系统</a>
</body>
</html>

根据/exit请求,编写销毁session对象的类

package com.bjpowernode.javaweb;

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 javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.javaweb
 * @Project:JavaWeb
 * @name:ExitServlet
 * @Date:2022/12/4 14:35
 */
@WebServlet("/exit")
public class ExitServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取session对象
        HttpSession session = request.getSession(false);
        if (session != null) {
            // 销毁session
            session.invalidate();
        }
    }
}

(4)AttributeListener的使用

①我们知道对于域对象都有setAttribute、getAttribute、removeAttribute方法,分别可以向域中存数据、取数据、清除数据;所以对于AttributeListener肯定是和这些处理域中数据有关。

②实际上对于ServletContextAttributeListener、ServletRequestAttributeListener 、HttpSessionAttributeListener这三个对象都有attributeAdded、attributeRemoved、attributeReplaced方法;表示:向域当中存储数据的时候调用、向域当中删除数据的时候调用、向域当中替换数据的时候调用。

③这里以HttpSessionAttributeListener对象为例:

编写HttpSessionAttributeListener监听器

package com.bjpowernode.javaweb.servlet;

import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.javaweb.servlet
 * @Project:JavaWeb
 * @name:MyHttpSessionAttributeListener
 * @Date:2022/12/4 14:46
 */
@WebListener
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
    // 向session域当中存储数据的时候,以下方法被WEB服务器调用。
    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
        System.out.println("session data add");
    }

    // 将session域当中存储的数据删除的时候,以下方法被WEB服务器调用。
    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {
        System.out.println("session data remove");
    }

    // session域当中的某个数据被替换的时候,以下方法被WEB服务器调用。
    @Override
    public void attributeReplaced(HttpSessionBindingEvent se) {
        System.out.println("session data replace");
    }
}

编写Servlet类用来处理域中的数据

当发送http://localhost:8080/servlet15/session/attribute/test 就能触发上面的监听器;

注意:调用getAttribute方法不会触发,只有setAttribute方法和removeAttribute方法才会触发

package com.bjpowernode.javaweb;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.javaweb
 * @Project:JavaWeb
 * @name:HttpSessionAttributeServlet
 * @Date:2022/12/4 14:49
 */
@WebServlet("/session/attribute/test")
public class HttpSessionAttributeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取session对象
        HttpSession session = request.getSession();

        // 向session域中存储数据
        session.setAttribute("user", "zhangsan");

        // 替换,覆盖上面的数据
        session.setAttribute("user", "lisi");

        // 删除
        session.removeAttribute("user");
    }
}

4、HttpSessionBindingListener

(1)前面我们已经讲解了关于域对象的监听器,九个监听器中就已经学习了6个;接下来就先分析一下HttpSessionBindingListener;顾名思义就是关于数据绑定的!

(2)下面就通过一个例子来学习一下HttpSessionBindingListener监听器

        创建一个user1类实现监听器(不需要@WebListener注解),并重写方法

        创建一个user2类不实现监听器

对比当数据放入放入域当中,两者会有什么区别:

①普通的user1类实现监听器,并重写监听器中两个方法

package com.bjpowernode.javaweb.bean;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

/**
 * 普通的java类。但是它实现了:HttpSessionBindingListener
 */
public class User1 implements HttpSessionBindingListener {

    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        System.out.println("绑定数据");
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        System.out.println("解绑数据");
    }

    private String usercode;
    private String username;
    private String password;

    public User1(String usercode, String username, String password) {
        this.usercode = usercode;
        this.username = username;
        this.password = password;
    }

    public User1() {
    }

    public String getUsercode() {
        return usercode;
    }

    public void setUsercode(String usercode) {
        this.usercode = usercode;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

②普通的user2类不实现监听器

package com.bjpowernode.javaweb.bean;

/**
 * 普通的java类。
 */
public class User2 {
    private String usercode;
    private String username;
    private String password;

    public User2() {
    }

    public User2(String usercode, String username, String password) {
        this.usercode = usercode;
        this.username = username;
        this.password = password;
    }

    public String getUsercode() {
        return usercode;
    }

    public void setUsercode(String usercode) {
        this.usercode = usercode;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

③编写一个servlet类,把这两种数据都存进去

发现实现监听器的user1类会触发绑定事件!

package com.bjpowernode.javaweb.servlet;

import com.bjpowernode.javaweb.bean.User1;
import com.bjpowernode.javaweb.bean.User2;

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 javax.servlet.http.HttpSession;

import java.io.IOException;

@WebServlet("/session/bind")
public class HttpSessionBindingListenerServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取session对象
        HttpSession session = request.getSession();

        // 准备两个对象:User1 User2
        User1 user1 = new User1("111", "zhangsan", "123");
        User2 user2 = new User2("111", "zhangsan", "123");

        // 将user1存储到session域
        session.setAttribute("user1", user1);

        // 将user2存储到session域
        session.setAttribute("user2", user2);
    }
}

(3)区分:HttpSessionAttributeListener 和 HttpSessionBindingListener

😊HttpSessionAttributeListener监听器

①该监听器是需要使用@WebListener注解进行标注的(或者使用web.xml文件进行配置)

该监听器监听的是session域中数据的变化。只要数据变化,则执行相应的方法;主要监测点在session域对象上。

③监听的是session域,只要把数据放入session域就进行监听!

😊HttpSessionBindingListener监听器

①该监听器是不需要使用@WebListener进行标注,类直接实现即可。

②假设User类实现了该监听器,那么User对象在被放入session的时候触发bind事件,User对象从session中删除的时候,触发unbind事件。

③假设Customer类没有实现该监听器,那么Customer对象放入session或者从session删除的时候,不会触发bind和unbind事件。

 ④监听的是普通的java对象,那个类实现了这个监听器,就监听那个类!

😊总结:

①对于HttpSessionAttributeListener监听的是任何种类的对象,只要放入session域当中就可以;上述user1和user2都可以触发!

②对于HttpSessionBindingListener监听的是特殊的对象,只有实现HttpSessionBindingListener接口的才可以;上述只有user1才能触发!

(4)那么这两个监听器有什么用呢?

我们通过一个简单的业务需求了解一下:
业务1:编写一个功能,记录该网站实时的在线用户的个数

我们可以通过服务器端有没有分配session对象,因为一个session代表了一个用户。有一个session就代表有一个用户。如果你采用这种逻辑去实现的话,session有多少个,在线用户就有多少个。这种方式的话:HttpSessionListener够用了。session对象只要新建,则count++,然后将count存储到ServletContext域当中,在页面展示在线人数即可!

业务2:只统计登录的用户的在线数量

用户登录的标志是什么?session中曾经存储过User类型的对象。那么这个时候可以让User类型的对象实现HttpSessionBindingListener监听器,只要User类型对象存储到session域中,则count++,然后将count++存储到ServletContext对象中。页面展示在线人数即可。

5、HttpSessionIdListener & HttpSessionActivationListener

这两个监听器不常用,这里只简单了解即可:

(1)HttpSessionIdListener:session的id发生改变的时候,监听器中的唯一一个方法就会被调用。

(2)HttpSessionActivationListener:监听session对象的钝化和活化的。

①钝化:session对象从内存存储到硬盘文件。

②活化:从硬盘文件把session恢复到内存。

6、使用监听器统计网站在线人数

实现oa项目中当前登录在线的人数!

(1)什么代表着用户登录了?

😊session.setAttribute("user", userObj); User类型的对象只要往session中存储过,表示有新用户登录。

(2)什么代表着用户退出了?

😊session.removeAttribute("user"); User类型的对象从session域中移除了。

😊或者有可能是session销毁了。(session超时) 。

(3)思考:我们要先思考一下寻访到什么域里面?

统计这个项目当汇总的登录在线人数,一个人一个的(session)以下的域肯定都不行,所以只能使用application域(ServletContext)。

①编写User类实现监听器的接口;然后修改关于所有session.getAttribute的代码

package com.bjpowernode.oa.bean;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

/**
 * @Author:朗朗乾坤
 * @Package:com.bjpowernode.oa.bean
 * @Project:JavaWeb
 * @name:User
 * @Date:2022/12/4 16:18
 */
public class User implements HttpSessionBindingListener {
    // 重写两个方法
    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        // 用户登录了
        // 相当于User类型的对象向session域当中存放
        // 获取application域对象
        // event.getSession()获取到session;在调用getServletContext()获取到域对象
        ServletContext application = event.getSession().getServletContext();
        // 获取到在线人数
        Object onlioncount = application.getAttribute("onlioncount");
        // 第一个用户登录,里面什么都没有,返回的是一个null
        if (onlioncount == null) {
            application.setAttribute("onlioncount",1);
        }else {
            // 直接 onlioncount++有问题,前面是Object类型,强转
            Integer count = (Integer)onlioncount;
            count++;
            // 在存入域当中
            application.setAttribute("onlioncount",count);
        }
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        // 用户退出了
        // 相当于User类型的对象向session域当中删除
        // 获取application域对象
        ServletContext application = event.getSession().getServletContext();
        // 获取域当中的数据,肯定不是空
        Integer onlioncount = (Integer) application.getAttribute("onlioncount");
        onlioncount--;
        // 在存入域当中
        application.setAttribute("onlioncount",onlioncount);
    }

    // 定义属性
    private String username;
    private String password;

    // 构造方法
    public User() {
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    // setter and getter
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

②修改UserServlet类和WelcomeServlet

// 把用户名放进session
session.setAttribute("username",username);

// 改为这样存
User user = new User(username, password);
session.setAttribute("user",user);

③修改过滤器LoginFilter

if("/index.jsp".equals(servletPath) || "/welcome".equals(servletPath) ||
                "/dept/login".equals(servletPath) || "/dept/exit".equals(servletPath)
                || (session != null && session.getAttribute("username") != null)){
// username改为user,因为前面存储的名字变了
if("/index.jsp".equals(servletPath) || "/welcome".equals(servletPath) ||
                "/dept/login".equals(servletPath) || "/dept/exit".equals(servletPath)
                || (session != null && session.getAttribute("user") != null)){

④修改list.jsp页面

<h3>欢迎${username}登录</h3>
<!--修改为-->
<h3>欢迎${user.username}登录,在线人数${onlioncount}人</h3>

⑤最终达到的效果

假如开了两个浏览器,登录了两次

点击退出登录,刷新另一个浏览器的页面 

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

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

相关文章

【编译原理】实验二:NFA到DFA

目录 实验二 NFA 到 DFA 一、实验目的 二、预备知识 三、实验内容 NFA向DFA的转换的思路 NFA和DFA之间的联系 NFAToDFA.h 文件 main.c 文件 RegexpToPost.c 文件 PostToNFA.c 文件 NFAFragmentStack.c 文件 PostToNFA.h 文件 NFAFragmentStack.h 文件 NFAStateStack.h 文件 dem…

【C++】使用yaml-cpp操作yaml文件

目录 1 安装yaml-cpp 2 工程结构 &#xff08;1&#xff09;test.yaml的内容 &#xff08;2&#xff09;CmakeLists.txt &#xff08;3&#xff09;代码 3 运行结果 4 报错处理 1 安装yaml-cpp &#xff08;1&#xff09;cd 到yaml-cpp下载的目的路径 例如&#xff1a;…

spring之反射机制之Spring-DI核心实现

文章目录前言一、回顾反射机制之反射调用方法1、编写一个方法类SomeService2、通过反射机制调用SomeService类中的方法二、反射机制之Spring-DI核心实现前言 调用一个方法当中含有几个要素&#xff1f; 1、调用哪个对象 2、调用哪个方法 3、调用方法的时候传什么参数 4、方法执…

一文弄懂 React ref

前言 对于 Ref 理解与使用&#xff0c;一些读者可能还停留在用 ref 获取真实 DOM 元素和获取类组件实例层面上 其实 ref 除了这两项常用功能之外&#xff0c;还有很多别的小技巧 通过本篇文章的学习&#xff0c;你将收获 React ref 的基本和进阶用法&#xff0c;并且能够明白…

LeetCode HOT 100 —— 621. 任务调度器

题目 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行&#xff0c;并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间&#xff0c;CPU 可以完成一个任务&#xff0c;或者处于待命状态。 然…

使用 SwiftUI 布局协议构建六边形网格,如何制作在六边形网格中显示子视图的通用 SwiftUI 容器

我们将要制作的组件可以作为Swift 包使用。 SwiftUI 非常擅长构建矩形框架的层次结构。随着最近的加入,Grid它变得更好了。然而,今天我们要构建一个疯狂的六边形布局。当然,没有专门的布局类型。所以我们用协议建立我们自己的Layout! 绘制一个六边形 让我们首先为我们的…

在linux中配置redis去中心化集群

目录 前情回顾 一、集群配置 二、启动redis集群 三、检验是否成功 成功&#xff01; 前情回顾 linux中配置redis主从复制及开启哨兵模式 一、集群配置 查看所有的redis服务进程 ps -ef | grep redis 关闭所有的redis服务&#xff08;6379,6380,6381) kill -9 99168 kill …

第十章:数据库恢复技术

1、【多选题】下列哪些属于事务的特征&#xff1a; 正确答案&#xff1a; AD 2、【多选题】下列关于故障恢复的说法正确的是&#xff1a; 正确答案&#xff1a; BC 3、【多选题】下列说法错误的是&#xff1a; 正确答案&#xff1a; AB

无线通信网络优化的自动路测系统设计(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 无线通信网络是一个动态的网络&#xff0c;无线网络优化是一项贯穿于整个网络发展全过程的长期工程。在网络建成投入运营以后,…

学习笔记 - Word、WPS分别设置背景色

学习笔记 - Word、WPS分别设置背景色前言实现原理实现步骤模拟背景色1. 插入矩形形状2. 调整矩形&#xff1a;位置、文字环绕、大小。3. 调整颜色实现按节分别设置1. 插入分节符2. 取消“同前节”3. 矩形入进页眉建议场景参考资料前言 Word、WPS 都没有自带此功能。只能统一设…

node.js+uni计算机毕设项目基于微信小程序的校园快递代取平台(程序+小程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等…

第十一章:并发控制

1、【多选题】二级封锁协议能够避免数据库哪些一致性问题 正确答案&#xff1a; AB 2、【多选题】下列说法正确的是&#xff1a; 正确答案&#xff1a; ABC 3、【多选题】下列哪些是解决死锁的方法&#xff1a; 正确答案&#xff1a; ABC

node.js+uni计算机毕设项目互联网教育系统小程序(程序+小程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等…

k8s-dashboard布署

k8s-dashboard布署Kubernetes dashboard作用获取Kubernetes dashboard资源清单文件修改并部署kubernetes dashboard资源清单文件访问Kubernetes dashboardKubernetes dashboard作用 通过dashboard能够直观了解Kubernetes集群中运行的资源对象通过dashboard可以直接管理&#x…

标准的晋升 PPT 长什么样子?互联网职场晋升内幕!想升职加薪?得这么干……...

如果你真的想顺利地升职加薪&#xff0c;就得从现在开始&#xff0c;重新系统地理解晋升到底是怎么回事。面评技巧导学你可能会认为&#xff0c; “是金子总会发光的”&#xff0c;只要自己能力达到了&#xff0c; 晋升就是“水到 渠成”的事情。毕竟评委的眼睛都是雪亮的&am…

node中,path.join和path.resolve的区别

1. path.join和path.resolve的区别 path.join 拼接路径能够识别 \ path.resolve 从当前的执行路径&#xff0c;解析出绝对路径不能识别 \ &#xff0c;会被当成根路径 注意下面的例子&#xff0c;是从当前的执行路径&#xff0c;解析出绝对路径 使用 process.cwd() 可以获取…

2023年中国博士后科学基金资助指南发布

今日&#xff0c;博管会发布了2023年中国博士后科学基金资助指南&#xff0c;内容上有较大的变化&#xff1a;1.面上资助不再分设一等、二等资助&#xff0c;资助标准统一调整为自然科学资助标准8万元&#xff0c;社会科学资助标准5万元&#xff1b;2.申请人申报周期从2个月调整…

AiFlow大数据框架应用简介

文章大纲1. 平台定位2. 平台特点一站建模智能分析交互分析通用部署3. 项目案例ETL 过程样例物料分类业务规则建模合作1. 平台定位 数据挖掘平台在此起到数据运营的承上启下的环节&#xff0c;主要负责数据的挖掘分析、ETL、数据检测。 平台支持自动建模、可视化交互建模、嵌入…

JavaScript:队列的封装及面试题击鼓传花队列方法实现案例

队列的定义&#xff1a;队列简称队。是一种操作受限的线性表&#xff0c;只允许在表的一端进行插入&#xff0c;而在表的另一端进行删除。向队列中插入元素称为入队或进队&#xff1b;删除元素称为出队或离队。其操作特性为先进先出&#xff08;First In First Out&#xff0c;…

【金猿人物展】天云数据雷涛:从数据湖到湖仓一体再到数据编织,完成的是燃油车到油电混再到纯电技术的改造...

‍雷涛本文由天云数据CEO雷涛撰写并投递参与“数据猿年度金猿策划活动——2022大数据产业趋势人物榜单及奖项”评选。‍数据智能产业创新服务媒体——聚焦数智 改变商业这一两年&#xff0c;北美以Facebook、谷歌为驱动的存算分离的虚拟数仓架构&#xff0c;正在非常快速的洗牌…