Java笔记18

news2025/2/24 22:03:59

2-10-3Cookie&Session

1.会话跟踪技术概述

  • 会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应
  • 会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据
  • HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享

2.Cookie基本使用

  • Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问
  • Cookie基本使用

发送Cookie

1.创建Cookie对象,设置数据

Cookie cookie = new Cookie("key","value");

2.发送Cookie到客户端:使用response对象

response.add Cookie(cookie);

获取Cookie

3.获取客户端携带的所有Cookie,使用request对象

Cookie[] cookies = request.getCookies();

4.遍历数组,获取每一个Cookie对象:for

5.使用Cookie对象方法获取数据

cookie.getName();

cookie.getValue();

    3.Cookie原理

    Cookie的实现是基于HTTP协议的

    • 响应头:set-cookie
    • 请求头:cookie

    工作原理步骤

    1. 服务器发 Cookie:用户访问网页,服务器处理请求时,在 HTTP 响应头用 Set - Cookie 字段发 Cookie 给浏览器。比如服务器想记住用户身份,就发个含身份信息的 Cookie。
    2. 浏览器存 Cookie:浏览器收到响应,解析 Set - Cookie 字段,把 Cookie 存本地,有内存和硬盘两种存储方式。
    3. 浏览器传 Cookie:浏览器再次访问同一服务器时,会在 HTTP 请求头的 Cookie 字段带上之前存的 Cookie 信息。
    4. 服务器用 Cookie:服务器收到请求,解析 Cookie 字段获取信息,根据信息做相应处理,像识别用户身份。

    Cookie 属性作用

    • Name - Value:存具体数据。
    • Domain 和 Path:限定能访问 Cookie 的域名和页面路径。
    • Expires/Max - Age:设定 Cookie 过期时间,没设就是会话 Cookie,关浏览器就删。
    • Secure:让 Cookie 只在 HTTPS 请求中传输,更安全。
    • HttpOnly:使 Cookie 只能通过 HTTP 请求访问,防脚本攻击偷信息。

    4.Cookie使用细节

    Cookie存活时间

    默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁

    setMaxAge(int seconds):设置Cookie存活时间

    1.正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。至到时间自动删除

    2.负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁

    3.零:删除对应Cookie

    //发送Cookie
    //1. 创建Cookie对象
    Cookie cookie = new Cookie("username", "zs");
    //设置存活时间 ,1周 7天
    cookie.setMaxAge(60*60*24*7);
    //2. 发送Cookie,response
    response.addCookie(cookie);
    }

    5.Cookie使用细节-存储中文

    • Cookie存储中文
      • Cookie不能直接存储中文
      • 如需要存储,则需要进行转码:URL编码
    //1. 获取COOKIE数组
    Cookie[] cookies = request.getCookies();
    
    //2. 遍历数组
    for (Cookie cookie : cookies) {
        //3. 获取数据
        String name = cookie.getName();
        if("username".equals(name)){
            String value = cookie.getValue();
            //URL解码
            value = URLDecoder.decode(value, "UTF-8");
    
            System.out.println(name+":"+value);
        }
    }

    6.Session基本使用

    • 服务端会话跟踪技术:将数据保存到服务端
    • JavaEE提供HttpSession接口,来实现一次会话的多次请求间数据共享功能
    • 使用:

    1.获取Session对象

    Http Session session = request.getSession();

    2.Session对象功能:

    • void setAttribute(String name, Objecto):存储数据到session 成中
    • Object getAttribute(String name):根据key,获取值
    • void removeAttribute(String name):根据key,删除该键值双时

    7.Session原理

    //存储到Session中
    //1. 获取Session对象
    HttpSession session = request.getSession();
    //2. 存储数据
    session.setAttribute("username", "zs");
    //获取数据,从session中
    //1. 获取Session对象
    HttpSession session = request.getSession();
    //2. 获取数据
    Object username = session.getAttribute("username");
    System.out.println(username);
    }

    8.Session-使用细节

    • Session钝化、活化:
      • 服务器重启后,Session中的数据是否还在?
        • 钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘的文件中
        • 活化:再次启动服务器后,从文件中加载数据到Session中
    • Seesion销毁:
      • 默认情况下,无操作,30分钟自动销毁

    <session-config>

    <session-timeout>30</session-timeout>

    </session-config>

    •         调用Session对象的invalidate()方法

    小结:

    • Cookie和Session都是来完成一次会话内多次请求间数据共享的
    • 区别:
      • 存储位置:Cookie是将数据存储在客户端,Session将数据存储在服务端
      • 安全性:Cookie不安全,Session安全
      • 数据大小:Cookie最大3KB,Session无大小限制
      • 存储时间:Cookie可以长期存储,Session默认30分钟
      • 服务器性能:Cookie不占服务器资源,Session占用服务器资源

    案例:

    用户登录:

    Web层

    UserMapper

    public interface UserMapper {
        /**
         * 根据用户名和密码查询用户对象
         * @param username
         * @param password
         * @return
         */
        @Select("select * from tb_user where username = #{username} and password = #{password}")
        User select(@Param("username") String username,@Param("password") String password);
    
        /**
         * 根据用户名查询用户对象
         * @param username
         * @return
         */
        @Select("select * from tb_user where username = #{username}")
        User selectByUsername(String username);
    /**
     * 添加用户
     * @param user
     */
    @Insert("insert into tb_user values(null,#{username},#{password})")
    void add(User user);
    }

    Service层

    UserService

    public class UserService {
        SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
    
        /**
         * 登录方法
         * @param username
         * @param password
         * @return
         */
        public User login(String username, String password){
            //2. 获取SqlSession
            SqlSession sqlSession = factory.openSession();
            //3. 获取UserMapper
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            //4. 调用方法
            User user = mapper.select(username, password);
    
            //释放资源
            sqlSession.close();
    
            return user;
        }
    }

    Dao层
    LoginServlet

    private UserService service = new UserService();
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
        //1. 获取用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
    
        //2. 调用service查询
        User user = service.login(username, password);
    
        //3. 判断
        if(user != null){
            //登录成功,跳转到查询所有的BrandServlet
            //将登陆成功后的user对象,存储到session
            HttpSession session = request.getSession();
            session.setAttribute("user", user);
    
            String contextPath = request.getContextPath();
            response.sendRedirect(contextPath+"/selectAllServlet");
        }else {
            // 登录失败,
            // 存储错误信息到request
            request.setAttribute("login_msg", "用户名或密码错误");
            // 跳转到login.jsp
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        }
    }

    案例:记住用户

    • 如果用户勾选"记住用户",则下次访问登陆页面自动填充用户名密码
    • 如何自动填充用户名和密码?
      • 1.将用户名和密码写入Cookie中,并且持久化存储Cookie,下次访问浏览器会自动携带Cookie
      • 2.在页面获取Cookie数据后,设置到用户名和密码框中
    • 何时写Cookie?
      • 1.登录成功
      • 2.用户勾选记住用户复选框
    private UserService service = new UserService();
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
        //1. 获取用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
    
        //获取复选框数据
        String remember = request.getParameter("remember");
    
        //2. 调用service查询
        User user = service.login(username, password);
    
        //3. 判断
        if(user != null){
            //登录成功,跳转到查询所有的BrandServlet
    
            //判断用户是否勾选记住我
            if("1".equals(remember)){
                //勾选了,发送Cookie
                //1. 创建Cookie对象
                Cookie c_username = new Cookie("username",username);
                Cookie c_password = new Cookie("password",password);
                //设置Cookie的存活时间
                c_username.setMaxAge(60 * 60 * 24 * 7);
                c_password.setMaxAge(60 * 60 * 24 * 7);
                //2. 发送
                response.addCookie(c_username);
                response.addCookie(c_password);
    }
                    
    
            //将登陆成功后的user对象,存储到session
            HttpSession session = request.getSession();
            session.setAttribute("user", user);
    
            String contextPath = request.getContextPath();
            response.sendRedirect(contextPath+"/selectAllServlet");
        }else {
            // 登录失败,
            // 存储错误信息到request
            request.setAttribute("login_msg", "用户名或密码错误");
            // 跳转到login.jsp
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        }
    }

    案例:记住用户获取Cookie

    2.在页面获取Cookie数据后,设置到用户名和密码框中:

    ${cookie.key.value}//key指存储在cookie中的键名称

    <body>
    <div id="loginDiv" style="...">
        <form action="/brand-demo/loginServlet" id="form">
            <h1 id="loginMsg">LOGIN IN</h1>
            <div id="errorMsg">${login_msg}</div>
            <p>Username:<input id="username" name="username" value="${cookie.username.value}" type="text"></p>
            <p>Password:<input id="password" name="password" value="${cookie.password.value}" type="password">
            <p>Remember:<input id="remember" name="remember" value="1" type="checkbox"></p>
            <div id="subDiv">
                <input type="submit" class="button" value="login up">
                <input type="reset" class="button" value="reset">
                <a href="register.html">没有账号?</a>
            </div>
        </form>
    </div>
    </body>

    案例:用户注册

    注册功能:保存用户信息到数据库

    验证码功能:

    展示验证码:展示验证码图片,并可以点击切换

    校验验证码:验证码填写不正确,则注册失败


    Dao层

    UserMapper

    public interface UserMapper {
        /**
         * 根据用户名和密码查询用户对象
         * @param username
         * @param password
         * @return
         */
        @Select("select * from tb_user where username = #{username} and password = #{password}")
        User select(@Param("username") String username,@Param("password") String password);
    
        /**
         * 根据用户名查询用户对象
         * @param username
         * @return
         */
        @Select("select * from tb_user where username = #{username}")
        User selectByUsername(String username);
    /**
     * 添加用户
     * @param user
     */
    @Insert("insert into tb_user values(null,#{username},#{password})")
    void add(User user);
    }

    Service层

    UserService

    public boolean register(User user){
        //2. 获取SqlSession
        SqlSession sqlSession = factory.openSession();
        //3. 获取UserMapper
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
        //4. 判断用户名是否存在
        User u = mapper.selectByUsername(user.getUsername());
    
        if(u == null){
            // 用户名不存在,注册
            mapper.add(user);
            sqlSession.commit();
        }
    }

    Web层

    RegisterServlet

    @WebServlet("/registerServlet")
    public class RegisterServlet extends HttpServlet {
        private UserService service = new UserService();
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
            //1. 获取用户名和密码数据
            String username = request.getParameter("username");
            String password = request.getParameter("password");
    
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
    
            //2. 调用service 注册
            boolean flag = service.register(user);
            //3. 判断注册成功与否
            if(flag){
                //注册功能, 跳转登陆页面
                request.setAttribute("register_msg", "注册成功,请登录");
                request.getRequestDispatcher("/login.jsp").forward(request,response);
            }else {
                //注册失败, 跳转到注册页面
                request.setAttribute("register_msg", "用户名已存在");
              request.getRequestDispatcher("/register.jsp").forward(request,response);
            }
            }
    
            @Override
            protected void doPost(HttpServletRequest request, HttpServletResponse         response) throws ServletException {
                this.doGet(request, response);
    }
        }
    }

    案例:验证码

    注册功能:保存用户信息到数据库

    验证码功能:

    展示验证码:展示验证码图片,并可以点击切换

    校验验证码:验证码填写不正确,则注册失败

    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.Random;
    
    public class CheckCodeUtil {
        // 验证码字符集
        private static final String CHAR_SET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        // 验证码长度
        private static final int CODE_LENGTH = 4;
        // 图片宽度
        private static final int IMG_WIDTH = 100;
        // 图片高度
        private static final int IMG_HEIGHT = 50;
    
        /**
         * 生成验证码图片并保存到指定文件,返回验证码字符串
         * @param width 图片宽度
         * @param height 图片高度
         * @param filePath 保存图片的文件路径
         * @return 验证码字符串
         * @throws IOException 保存图片时可能抛出的异常
         */
        public static String outputVerifyImage(int width, int height, String filePath) throws IOException {
            String verifyCode = generateVerifyCode();
            BufferedImage image = createImage(width, height, verifyCode);
            saveImage(image, filePath);
            return verifyCode;
        }
    
        /**
         * 生成随机验证码字符串
         * @return 验证码字符串
         */
        private static String generateVerifyCode() {
            Random random = new Random();
            StringBuilder code = new StringBuilder();
            for (int i = 0; i < CODE_LENGTH; i++) {
                int index = random.nextInt(CHAR_SET.length());
                code.append(CHAR_SET.charAt(index));
            }
            return code.toString();
        }
    
        /**
         * 创建包含验证码的图片
         * @param width 图片宽度
         * @param height 图片高度
         * @param verifyCode 验证码字符串
         * @return 包含验证码的图片
         */
        private static BufferedImage createImage(int width, int height, String verifyCode) {
            // 创建 BufferedImage 对象
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics g = image.getGraphics();
            // 设置背景颜色
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, width, height);
            // 设置字体
            g.setFont(new Font("Arial", Font.BOLD, 20));
            // 设置文字颜色
            g.setColor(Color.BLACK);
            // 绘制验证码字符
            for (int i = 0; i < verifyCode.length(); i++) {
                g.drawString(String.valueOf(verifyCode.charAt(i)), 20 * i + 10, 30);
            }
            // 绘制干扰线
            drawNoiseLines(g, width, height);
            g.dispose();
            return image;
        }
    
        /**
         * 绘制干扰线
         * @param g 图形上下文
         * @param width 图片宽度
         * @param height 图片高度
         */
        private static void drawNoiseLines(Graphics g, int width, int height) {
            Random random = new Random();
            g.setColor(Color.GRAY);
            for (int i = 0; i < 5; i++) {
                int x1 = random.nextInt(width);
                int y1 = random.nextInt(height);
                int x2 = random.nextInt(width);
                int y2 = random.nextInt(height);
                g.drawLine(x1, y1, x2, y2);
            }
        }
    
        /**
         * 保存图片到指定文件
         * @param image 要保存的图片
         * @param filePath 保存图片的文件路径
         * @throws IOException 保存图片时可能抛出的异常
         */
        private static void saveImage(BufferedImage image, String filePath) throws IOException {
            File outputFile = new File(filePath);
            ImageIO.write(image, "jpg", outputFile);
        }
    
        public static void main(String[] args) {
            try {
                String filePath = "d://a.jpg";
                String checkCode = outputVerifyImage(IMG_WIDTH, IMG_HEIGHT, filePath);
                System.out.println("生成的验证码是: " + checkCode);
                System.out.println("验证码图片已保存到: " + filePath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    案例:校验验证码

    判断程序生成的验证码 和 用户输入的验证码是否一样,如果不一洋,则阻止注册

    验证码图片访问和提交注册表单是两次请求,所以要将程序生成的验证码存入Sessio

    CheckCodeServlet

    将验证码存入session

    // 生成验证码
    ServletOutputStream os = response.getOutputStream();
    String checkCode = CheckCodeUtil.outputVerifyImage(100, 50, os, 4);
    
    // 存入Session
    HttpSession session = request.getSession();
    session.setAttribute("checkCodeGen",checkCode);
    }

    RegisterServlet

    1.接收用户输入验证码

    2.比对

    // 获取用户输入的验证码
    String checkCode = request.getParameter("checkCode");
    
    // 程序生成的验证码,从Session获取
    HttpSession session = request.getSession();
    String checkCodeGen = (String) session.getAttribute("checkCodeGen");
    
    if(!checkCodeGen.equalsIgnoreCase(checkCode)){
        request.setAttribute("register_msg", "验证码错误");
        request.getRequestDispatcher("/register.jsp").forward(request, response);
        // 不允许注册
        return;
    }

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

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

    相关文章

    进程概念、PCB及进程查看

    文章目录 一.进程的概念进程控制块&#xff08;PCB&#xff09; 二.进程查看通过指令查看进程通过proc目录查看进程的cwd和exe获取进程pid和ppid通过fork()创建子进程 一.进程的概念 进程是一个运行起来的程序&#xff0c;而程序是存放在磁盘的&#xff0c;cpu要想执行程序的指…

    php session数据存储位置选择

    PHP session 数据的存储位置可以通过配置文件或者代码来进行设置。默认情况下&#xff0c;session 数据是存储在服务器的文件系统中的。你可以将 session 数据存储在其他地方&#xff0c;例如数据库、缓存等。 基础概念 PHP session默认情况下将数据存储在服务器端的临时文件中…

    计算机网络————(一)HTTP讲解

    基础内容分类 从TCP/IP协议栈为依托&#xff0c;由上至下、从应用层到基础设施介绍协议。 1.应用层&#xff1a; HTTP/1.1 Websocket HTTP/2.0 2.应用层的安全基础设施 LTS/SSL 3.传输层 TCP 4.网络层及数据链路层 IP层和以太网 HTTP协议 网络页面形成基本 流程&#xff1a…

    【Viewer.js】vue3封装图片查看器

    效果图 需求 点击图片放大可关闭放大的 图片 下载 cnpm in viewerjs状态管理方法 stores/imgSeeStore.js import { defineStore } from pinia export const imgSeeStore defineStore(imgSeeStore, {state: () > ({showImgSee: false,ImgUrl: ,}),getters: {},actions: {…

    数据结构之二叉树的定义及实现

    1. 树的概念 主要的定义&#xff1a; 节点的度&#xff1a;一个节点含有的子树的个数称为该节点的度&#xff1b;如上图&#xff1a;A的为6 叶节点或终端节点&#xff1a;度为0的节点称为叶节点&#xff1b;如上图&#xff1a;B&#xff0c;C&#xff0c;H&#xff0c;I等节点…

    Rust语言基础知识详解【一】

    1.在windows上安装Rust Windows 上安装 Rust 需要有 C 环境&#xff0c;以下为安装的两种方式&#xff1a; 1. x86_64-pc-windows-msvc&#xff08;官方推荐&#xff09; 先安装 Microsoft C Build Tools&#xff0c;勾选安装 C 环境即可。安装时可自行修改缓存路径与安装路…

    SQLMesh 系列教程9- 宏变量及内置宏变量

    SQLMesh 的宏变量是一个强大的工具&#xff0c;能够显著提高 SQL 模型的动态化能力和可维护性。通过合理使用宏变量&#xff0c;可以实现动态时间范围、多环境配置、参数化查询等功能&#xff0c;从而简化数据模型的开发和维护流程。随着数据团队的规模扩大和业务复杂度的增加&…

    【Deepseek】Linux 本地部署 Deepseek

    前言 本文介绍在 Linux 系统上部署 Deepseek AI。本文教程是面向所有想体验 AI 玩家的一个简易教程&#xff0c;因此即使是小白也可以轻松完成体验&#xff0c;话不多说立马着手去干。 [注]&#xff1a;笔者使用的系统为 Ubuntu 24.10 1. 关于 ollama Ollama 是一款开源应用…

    git,bash - 从一个远端git库只下载一个文件的方法

    文章目录 git,bash - 从一个远端git库只下载一个文件的方法概述笔记写一个bash脚本来自动下载get_github_raw_file_from_url.shreanme_file.shfind_key_value.sh执行命令 END git,bash - 从一个远端git库只下载一个文件的方法 概述 github上有很多大佬上传了电子书库&#xf…

    臻识相机,华夏相机,芊熠车牌识别相机加密解密

    臻识&#xff0c;华夏&#xff0c;芊熠这三种车牌识别相机解密我都试过了&#xff0c;可以正常解密成功&#xff0c;其它品牌我暂时没有测试。超级简单&#xff0c;免费的&#xff0c;白嫖无敌&#xff01; 流程&#xff1a; ①&#xff1a;先导出配置文件&#xff0c;例如我以…

    网络安全与措施

    &#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 # 网络安全问题概述 1) 数据安全 访问&#xff08;授权访问&#xff09;&#xff1b;存储&#xff08;容灾、备份或异地备份等&#xff09; 2) 应用程序 不能…

    前后端分离系统架构:基于Spring Boot的最佳实践

    前后端分离系统架构图描绘了一个基于Springboot的前端后台分离的系统架构。它强调了前端&#xff08;客户端&#xff09;与远程&#xff08;服务器&#xff09;的解耦&#xff0c;通过API接口进行交互&#xff0c;分别独立开发和部署。 前后端分离系统架构图 从上到下&#xff…

    内外网文件传输 安全、可控、便捷的跨网数据传输方案

    一、背景与痛点 在内外网隔离的企业网络环境中&#xff0c;员工与外部协作伙伴&#xff08;如钉钉用户&#xff09;的文件传输面临以下挑战&#xff1a; 安全性风险&#xff1a;内外网直连可能导致病毒传播、数据泄露。 操作繁琐&#xff1a;传统方式需频繁切换网络环境&…

    抖音试水AI分身;腾讯 AI 战略调整架构;百度旗下小度官宣接入DeepSeek...|网易数智日报

    抖音试水AI分身&#xff0c;字节旗下AI智能体平台扣子已与抖音打通&#xff0c;相关功能内测中 2月19日消息&#xff0c;钛媒体App独家获悉&#xff0c;字节旗下AI智能体开发平台扣子&#xff08;Coze&#xff09;已与抖音打通&#xff0c;抖音创作者可在扣子智能体平台打造AI分…

    红帽7基于kickstart搭建PXE环境

    Kickstart 文件是一种配置文件&#xff0c;用于定义 Linux 系统安装过程中的各种参数&#xff0c;如分区、网络配置、软件包选择等。system-config-kickstart 提供了一个图形界面&#xff0c;方便用户快速生成这些配置文件。 用户可以通过图形界面进行系统安装的详细配置&…

    安装PHPStudy 并搭建DVWA靶场

    目录 一、PHPStudy 简介 二、DVWA 简介 三、安装 PHPStudy 四&#xff1a;安装 DVWA 一、PHPStudy 简介 phpstudy傻瓜式的一键启动&#xff0c;支持WAMP、WNMP、LAMP、LNMP&#xff0c;一键切换环境&#xff08;nginxapahce&#xff09;,一键切换PHP版本&#xff08;5.1-7…

    SQL写法技巧

    目录 1.批量插入&#xff0c;查询&#xff0c;删除数据 缺点 实现方法 1.批量插入数据 2.批量查询数据 3.批量删除数据 4.批量修改数据 解释 2.树型表查询 方法一&#xff1a;递归(适用于多级的情况) 方法二&#xff1a;表的自连接 方法三&#xff1a;MySQL递归&am…

    Ryu:轻量开源,开启 SDN 新程

    1. Ryu 控制器概述 定位&#xff1a;轻量级、开源的SDN控制器&#xff0c;专为开发者和研究人员设计&#xff0c;基于Python实现。开发者&#xff1a;由日本NTT实验室主导开发&#xff0c;遵循Apache 2.0开源协议。核心理念&#xff1a;简化SDN应用开发&#xff0c;提供友好的…

    【核心算法篇十四】《深度解密DeepSeek量子机器学习:VQE算法加速的黑科技与工程实践》

    在经典计算机逼近物理极限的今天,量子计算正以指数级加速潜力颠覆传统计算范式。想象一下,一个需要超级计算机运算千年的化学分子模拟问题,用量子计算机可能只需几分钟——这就是DeepSeek团队在VQE(Variational Quantum Eigensolver)算法加速实践中创造的奇迹。根据,VQE作…

    “国补”带火手机换新,出售旧手机应如何保护个人信息安全

    在“国补”政策的推动下,手机换新热潮正席卷而来。“国补”以其诱人的补贴力度,成功激发了消费者更换手机的热情。无论是渴望体验最新技术的科技爱好者,还是对旧手机性能不满的普通用户,都纷纷投身到这场手机换新的浪潮之中。 随着大量消费者参与手机换新,二手手机市场迎来…