引擎切换pdf识别简历分析

news2024/11/18 11:25:57

文章目录

    • 1.EasyCode生成interview_history的crud
        • 1.在模板设置中手动指定逻辑删除的值
        • 2.生成代码,进行测试
    • 2.PDF识别关键字
        • 1.引入依赖
        • 2.代码概览
        • 3.PDFUtil.java
        • 4.keyword
          • 1.EndType.java
          • 2.FlagIndex.java
          • 3.WordType.java
          • 4.KeyWordUtil.java
    • 3.策略模式实现引擎切换&简历分析
        • 1.req和vo
          • 1.InterviewReq.java
          • 2.InterviewVO.java
        • 2.策略模式准备
          • 1.引擎策略枚举 EngineEnum.java
          • 2.引擎策略能力接口 InterviewEngine.java
          • 3.本地引擎具体策略 JiChiInterviewEngine.java
        • 3.业务
          • 1.InterviewController.java
          • 2.InterviewHistoryService.java
          • 3.InterviewHistoryServiceImpl.java
        • 4.测试

1.EasyCode生成interview_history的crud

1.在模板设置中手动指定逻辑删除的值

CleanShot 2024-07-21 at 16.11.30@2x

2.生成代码,进行测试

CleanShot 2024-07-21 at 16.36.26@2x

2.PDF识别关键字

1.引入依赖
        <!-- pdf解析器 -->
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.24</version>
        </dependency>
2.代码概览

CleanShot 2024-07-22 at 14.37.06@2x

3.PDFUtil.java
package com.sunxiansheng.interview.server.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Pattern;

@Slf4j
public class PDFUtil {

    private static Pattern pattern = Pattern.compile("\\s*|\t|\r|\n");

    /**
     * 获取pdf的text
     */
    public static String getPdfText(String pdfUrl) {

        PDDocument document = null;
        String text = "";
        try {
            URL url = new URL(pdfUrl);
            HttpURLConnection htpcon = (HttpURLConnection) url.openConnection();
            htpcon.setRequestMethod("GET");
            htpcon.setDoOutput(true);
            htpcon.setDoInput(true);
            htpcon.setUseCaches(false);
            htpcon.setConnectTimeout(10000);
            htpcon.setReadTimeout(10000);
            InputStream in = htpcon.getInputStream();
            document = PDDocument.load(in);
            PDFTextStripper stripper = new PDFTextStripper();
            stripper.setSortByPosition(true);
            stripper.setStartPage(0);
            stripper.setEndPage(Integer.MAX_VALUE);
            text = stripper.getText(document);
            text = pattern.matcher(text).replaceAll("");
            if (log.isInfoEnabled()) {
                log.info("识别到的pdf为{}", text);
            }
        } catch (Exception e) {
            log.error("获取pdf转为文字错误:{}", e.getMessage(), e);
        } finally {
            if (document != null) {
                try {
                    document.close();
                } catch (Exception e) {
                    log.error("close error", e);
                }
            }
        }
        return text;
    }


}
4.keyword
1.EndType.java
package com.sunxiansheng.interview.server.util.keyword;

/**
 * 结束类型定义
 *
 * @author minghu.zhang
 * @date 11:37 2020/11/11
 **/
public enum EndType {

    /**
     * 有下一个,结束
     */
    HAS_NEXT, IS_END
}

2.FlagIndex.java
package com.sunxiansheng.interview.server.util.keyword;

import java.util.List;

/**
 * 敏感词标记
 *
 * @author minghu.zhang
 */
public class FlagIndex {

    /**
     * 标记结果
     */
    private boolean flag;
    /**
     * 是否黑名单词汇
     */
    private boolean isWhiteWord;
    /**
     * 标记索引
     */
    private List<Integer> index;

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public List<Integer> getIndex() {
        return index;
    }

    public void setIndex(List<Integer> index) {
        this.index = index;
    }

    public boolean isWhiteWord() {
        return isWhiteWord;
    }

    public void setWhiteWord(boolean whiteWord) {
        isWhiteWord = whiteWord;
    }
}

3.WordType.java
package com.sunxiansheng.interview.server.util.keyword;

/**
 * 词汇类型
 *
 * @author minghu.zhang
 * @date 11:37 2020/11/11
 **/
public enum WordType {

    /**
     * 黑名单/白名单
     */
    BLACK, WHITE
}

4.KeyWordUtil.java
package com.sunxiansheng.interview.server.util.keyword;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;

import java.util.*;

public class KeyWordUtil {

    /**
     * 敏感词字典
     */
    private final static Map wordMap = new HashMap(1024);
    private static boolean init = false;

    public static boolean isInit() {
        return init;
    }

    /**
     * 获取敏感词列表
     *
     * @param text 输入文本
     */
    public static List<String> buildKeyWordsLists(final String text) {

        List<String> wordList = new ArrayList<>();
        char[] charset = text.toCharArray();
        for (int i = 0; i < charset.length; i++) {
            FlagIndex fi = getFlagIndex(charset, i, 0);
            if (fi.isFlag()) {
                if (fi.isWhiteWord()) {
                    i += fi.getIndex().size() - 1;
                } else {
                    StringBuilder builder = new StringBuilder();
                    for (int j : fi.getIndex()) {
                        char word = text.charAt(j);
                        builder.append(word);
                    }
                    wordList.add(builder.toString());
                }
            }
        }
        return wordList;

    }


    /**
     * 获取标记索引
     *
     * @param charset 输入文本
     * @param begin   检测起始
     * @param skip    文本距离
     */
    private static FlagIndex getFlagIndex(final char[] charset, final int begin, final int skip) {

        FlagIndex fi = new FlagIndex();
        Map current = wordMap;
        boolean flag = false;
        int count = 0;
        List<Integer> index = new ArrayList<>();
        for (int i = begin; i < charset.length; i++) {
            char word = charset[i];
            Map mapTree = (Map) current.get(word);
            if (count > skip || (i == begin && Objects.isNull(mapTree))) {
                break;
            }
            if (Objects.nonNull(mapTree)) {
                current = mapTree;
                count = 0;
                index.add(i);
            } else {
                count++;
                if (flag && count > skip) {
                    break;
                }
            }
            if ("1".equals(current.get("isEnd"))) {
                flag = true;
            }
            if ("1".equals(current.get("isWhiteWord"))) {
                fi.setWhiteWord(true);
                break;
            }
        }
        fi.setFlag(flag);
        fi.setIndex(index);
        return fi;

    }

    public static void addWord(Collection<String> wordList) {
        init = true;
        if (CollectionUtils.isEmpty(wordList)) {
            return;
        }
        WordType wordType = WordType.BLACK;
        Map nowMap;
        Map<String, String> newWorMap;
        // 迭代keyWordSet
        for (String key : wordList) {
            nowMap = wordMap;
            for (int i = 0; i < key.length(); i++) {
                // 转换成char型
                char keyChar = key.charAt(i);
                // 获取
                Object wordMap = nowMap.get(keyChar);
                // 如果存在该key,直接赋值
                if (wordMap != null) {
                    nowMap = (Map) wordMap;
                } else {
                    // 不存在则构建一个map,同时将isEnd设置为0,因为他不是最后一个
                    newWorMap = new HashMap<>(4);
                    // 不是最后一个
                    newWorMap.put("isEnd", String.valueOf(EndType.HAS_NEXT.ordinal()));
                    nowMap.put(keyChar, newWorMap);
                    nowMap = newWorMap;
                }

                if (i == key.length() - 1) {
                    // 最后一个
                    nowMap.put("isEnd", String.valueOf(EndType.IS_END.ordinal()));
                    nowMap.put("isWhiteWord", String.valueOf(wordType.ordinal()));
                }
            }
        }
    }
}

3.策略模式实现引擎切换&简历分析

1.req和vo
1.InterviewReq.java
package com.sunxiansheng.interview.api.req;

import com.sunxiansheng.interview.api.enums.EngineEnum;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;


@Getter
@Setter
public class InterviewReq implements Serializable {

    /**
     * pdf的url
     */
    private String url;

    /**
     * 分析引擎的名字(AI或者本地)
     */
    private String engine = EngineEnum.JI_CHI.name();

}

2.InterviewVO.java
package com.sunxiansheng.interview.api.vo;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.List;


@Getter
@Setter
public class InterviewVO implements Serializable {

    /**
     * 问题列表
     */
    private List<Interview> questionList;

    /**
     * 内部类(具体的问题信息)
     */
    @Data
    public static class Interview {
        /**
         * pdf识别出来的关键词(分类名-标签名)
         */
        private String keyWord;
        /**
         * 标签的分类id
         */
        private Long categoryId;
        /**
         * 标签id
         */
        private Long labelId;
    }

}

2.策略模式准备
1.引擎策略枚举 EngineEnum.java
package com.sunxiansheng.interview.api.enums;

import lombok.Getter;

/**
 * 引擎
 */
@Getter
public enum EngineEnum {

    JI_CHI,
    ALI_BL,

}

2.引擎策略能力接口 InterviewEngine.java
package com.sunxiansheng.interview.server.service;


import com.sunxiansheng.interview.api.enums.EngineEnum;
import com.sunxiansheng.interview.api.vo.InterviewVO;

import java.util.List;

/**
 * 引擎能力接口
 */
public interface InterviewEngine {

    /**
     * 标识引擎类型的能力
     */
    EngineEnum engineType();

    /**
     * 通过简历关键字获取面试关键字
     */
    InterviewVO analyse(List<String> KeyWords);

}

3.本地引擎具体策略 JiChiInterviewEngine.java
package com.sunxiansheng.interview.server.service.impl;

import com.sunxiansheng.interview.api.enums.EngineEnum;
import com.sunxiansheng.interview.api.vo.InterviewVO;
import com.sunxiansheng.interview.server.entity.po.SubjectCategory;
import com.sunxiansheng.interview.server.entity.po.SubjectLabel;
import com.sunxiansheng.interview.server.mapper.SubjectMapper;
import com.sunxiansheng.interview.server.service.InterviewEngine;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Description: 本地的引擎
 * @Author sun
 * @Create 2024/7/22 14:23
 * @Version 1.0
 */
@Component
public class JiChiInterviewEngine implements InterviewEngine {

    @Resource
    private SubjectMapper subjectMapper;

    /**
     * 所有的标签和
     */
    private List<SubjectLabel> labels;
    private Map<Long, SubjectCategory> categoryMap;

    // bean装载后初始化
    @PostConstruct
    public void init() {
        labels = subjectMapper.listAllLabel();
        // 收集成map,key为分类id,value为分类对象
        categoryMap = subjectMapper.listAllCategory().stream().collect(Collectors.toMap(
                SubjectCategory::getId, Function.identity()
        ));
    }

    /**
     * 枚举标识自己是本地引擎
     * @return
     */
    @Override
    public EngineEnum engineType() {
        return EngineEnum.JI_CHI;
    }

    /**
     * 根据关键词分析简历
     * @param KeyWords
     * @return
     */
    @Override
    public InterviewVO analyse(List<String> KeyWords) {
        // 判空
        if (CollectionUtils.isEmpty(KeyWords)) {
            return new InterviewVO();
        }
        // 首先过滤出所有是关键词的标签
        List<SubjectLabel> includedLabels = labels.stream().filter(item -> {
            return KeyWords.contains(item.getLabelName());
        }).collect(Collectors.toList());
        // map成InterviewVO.Interview
        List<InterviewVO.Interview> collect = includedLabels.stream().map(
                // label为是关键词的标签
                label -> {
                    InterviewVO.Interview interview = new InterviewVO.Interview();
                    // 根据标签来获取这个标签所在的分类
                    SubjectCategory subjectCategory = categoryMap.get(label.getCategoryId());
                    // 如果分类不为空,则将分类名和标签名format成 "分类名-标签名" 的格式作为KeyWord
                    if (Objects.nonNull(subjectCategory)) {
                        interview.setKeyWord(String.format("%s-%s", subjectCategory.getCategoryName(), label.getLabelName()));
                    } else {
                        interview.setKeyWord(label.getLabelName());
                    }
                    interview.setCategoryId(label.getCategoryId());
                    interview.setLabelId(label.getId());
                    return interview;
                }
        ).collect(Collectors.toList());

        InterviewVO interviewVO = new InterviewVO();
        interviewVO.setQuestionList(collect);
        return interviewVO;
    }
}
3.业务
1.InterviewController.java
package com.sunxiansheng.interview.server.controller;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Preconditions;
import com.sunxiansheng.interview.api.common.Result;
import com.sunxiansheng.interview.api.req.InterviewReq;
import com.sunxiansheng.interview.api.vo.InterviewVO;
import com.sunxiansheng.interview.server.convert.InterviewHistoryConvert;
import com.sunxiansheng.interview.server.entity.dto.InterviewHistoryDto;
import com.sunxiansheng.interview.server.entity.page.PageResult;
import com.sunxiansheng.interview.server.entity.req.InterviewHistoryReq;
import com.sunxiansheng.interview.server.entity.vo.InterviewHistoryVo;
import com.sunxiansheng.interview.server.service.InterviewHistoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * 模拟面试信息 前端控制器
 *
 * @author sun
 * @since 2024-07-21 16:03:42
 */
@Slf4j
@RestController
@RequestMapping("/interview")
public class InterviewController {
    /**
     * 服务对象
     */
    @Resource
    private InterviewHistoryService interviewHistoryService;

    /**
     * 分页查询数据
     *
     * @param req 筛选条件
     * @return 查询结果
     */
    @GetMapping("/queryPage")
    public Result<PageResult<InterviewHistoryVo>> queryByPage(@RequestBody InterviewHistoryReq req) {
        try {
            // 打印日志
            if (log.isInfoEnabled()) {
                log.info("分页查询数据入参{}", JSON.toJSONString(req));
            }

            // ============================== Preconditions 参数校验 ==============================

            // ============================== Preconditions 参数校验 ==============================

            // 将req转换为dto(如果req的字段符合service层的规范,不转也可以)
            InterviewHistoryDto interviewHistoryDto = InterviewHistoryConvert.INSTANCE.convertReqToDto(req);
            // 调用service层
            PageResult<InterviewHistoryVo> interviewHistoryVoPageResult = this.interviewHistoryService.queryByPage(interviewHistoryDto);
            return Result.ok(interviewHistoryVoPageResult);
        } catch (Exception e) {
            // 打印error日志
            log.error("分页查询数据!错误原因{}", e.getMessage(), e);
            return Result.fail(e.getMessage());
        }
    }

    /**
     * 分析简历
     */
    @PostMapping(value = "/analyse")
    public Result<InterviewVO> analyse(@RequestBody InterviewReq req) {
        try {
            if (log.isInfoEnabled()) {
                log.info("分析简历入参{}", JSON.toJSON(req));
            }
            Preconditions.checkArgument(!Objects.isNull(req), "参数不能为空!");
            Preconditions.checkArgument(!Objects.isNull(req.getEngine()), "引擎不能为空!");
            Preconditions.checkArgument(!Objects.isNull(req.getUrl()), "简历不能为空!");
            return Result.ok(interviewHistoryService.analyse(req));
        } catch (IllegalArgumentException e) {
            log.error("参数异常!错误原因{}", e.getMessage(), e);
            return Result.fail(e.getMessage());
        } catch (Exception e) {
            log.error("分析简历异常!错误原因{}", e.getMessage(), e);
            return Result.fail("分析简历异常!");
        }
    }

}

2.InterviewHistoryService.java
package com.sunxiansheng.interview.server.service;

import com.sunxiansheng.interview.api.req.InterviewReq;
import com.sunxiansheng.interview.api.vo.InterviewVO;
import com.sunxiansheng.interview.server.entity.dto.InterviewHistoryDto;
import com.sunxiansheng.interview.server.entity.page.PageResult;
import com.sunxiansheng.interview.server.entity.vo.InterviewHistoryVo;

/**
 * 面试汇总记录表(InterviewHistory)service接口
 *
 * @author sun
 * @since 2024-07-21 16:03:42
 */
public interface InterviewHistoryService {

    /**
     * 分页查询
     *
     * @param Dto 筛选条件
     * @return 查询结果
     */
    PageResult<InterviewHistoryVo> queryByPage(InterviewHistoryDto Dto);

    /**
     * 使用引擎分析简历
     *
     * @param req
     * @return
     */
    InterviewVO analyse(InterviewReq req);
}

3.InterviewHistoryServiceImpl.java
package com.sunxiansheng.interview.server.service.impl;

import com.google.common.base.Preconditions;
import com.sunxiansheng.interview.api.req.InterviewReq;
import com.sunxiansheng.interview.api.vo.InterviewVO;
import com.sunxiansheng.interview.server.convert.InterviewHistoryConvert;
import com.sunxiansheng.interview.server.entity.dto.InterviewHistoryDto;
import com.sunxiansheng.interview.server.entity.page.PageResult;
import com.sunxiansheng.interview.server.entity.page.SunPageHelper;
import com.sunxiansheng.interview.server.entity.po.InterviewHistoryPo;
import com.sunxiansheng.interview.server.entity.po.SubjectLabel;
import com.sunxiansheng.interview.server.entity.vo.InterviewHistoryVo;
import com.sunxiansheng.interview.server.mapper.InterviewHistoryMapper;
import com.sunxiansheng.interview.server.mapper.SubjectMapper;
import com.sunxiansheng.interview.server.service.InterviewEngine;
import com.sunxiansheng.interview.server.service.InterviewHistoryService;
import com.sunxiansheng.interview.server.util.PDFUtil;
import com.sunxiansheng.interview.server.util.keyword.KeyWordUtil;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 面试汇总记录表(InterviewHistory)service实现类
 *
 * @author sun
 * @since 2024-07-21 16:27:12
 */
@Service("interviewHistoryService")
public class InterviewHistoryServiceImpl implements InterviewHistoryService, ApplicationContextAware {

    @Resource
    private InterviewHistoryMapper interviewHistoryMapper;

    @Resource
    private SubjectMapper subjectMapper;

    /**
     * 存放所有的引擎策略的map
     */
    private static final Map<String, InterviewEngine> engineMap = new HashMap<>();

    /**
     * 在bean初始化之后立即被调用,这里用来得到所有的引擎对象并封装到map中,方便获取
     *
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 从上下文中获取所有具体的引擎
        Collection<InterviewEngine> engines = applicationContext.getBeansOfType(InterviewEngine.class).values();
        // 将这些引擎放到map中
        for (InterviewEngine engine : engines) {
            engineMap.put(engine.engineType().name(), engine);
        }
    }

    /**
     * 分页查询
     *
     * @param interviewHistoryDto 筛选条件,需要携带pageNo和pageSize以及查询条件
     * @return 分页结果
     */
    @Override
    public PageResult<InterviewHistoryVo> queryByPage(InterviewHistoryDto interviewHistoryDto) {
        // 将dto转换为po
        InterviewHistoryPo interviewHistoryPo = InterviewHistoryConvert.INSTANCE.convertDtoToPo(interviewHistoryDto);
        // 使用 SunPageHelper 执行分页操作
        PageResult<InterviewHistoryPo> paginate = SunPageHelper.paginate(interviewHistoryDto.getPageNo(), interviewHistoryDto.getPageSize(),
                () -> interviewHistoryMapper.count(interviewHistoryPo),
                (offset, size) -> interviewHistoryMapper.queryPage(interviewHistoryPo, offset, size)
        );
        // 将po转换为vo
        PageResult<InterviewHistoryVo> interviewHistoryVoPageResult = InterviewHistoryConvert.INSTANCE.convertPageResult(paginate);
        return interviewHistoryVoPageResult;
    }

    /**
     * 分析简历
     *
     * @param req
     * @return
     */
    @Override
    public InterviewVO analyse(InterviewReq req) {
        // 从pdf中获取关键词
        List<String> keyWords = buildKeyWords(req.getUrl());
        // 从map中获取处理的引擎
        InterviewEngine engine = engineMap.get(req.getEngine());
        Preconditions.checkArgument(!Objects.isNull(engine), "引擎不能为空!");
        // 使用获取到的引擎来分析简历
        return engine.analyse(keyWords);
    }

    /**
     * 分析pdf来获取关键词
     *
     * @param url
     * @return
     */
    private List<String> buildKeyWords(String url) {
        String pdfText = PDFUtil.getPdfText(url);
        if (!KeyWordUtil.isInit()) {
            // 数据库中查询所有标签,作为敏感词放到KeyWordUtil
            List<String> list = subjectMapper.listAllLabel().stream().map(SubjectLabel::getLabelName).collect(Collectors.toList());
            KeyWordUtil.addWord(list);
        }
        // 与数据库中查询出来的敏感词来进行比对,得到关键字列表
        return KeyWordUtil.buildKeyWordsLists(pdfText);
    }

}

4.测试

CleanShot 2024-07-22 at 15.44.39@2x

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

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

相关文章

QT-window记事本

QT-window记事本 一、演示效果二、核心代码三、下载连接 一、演示效果 二、核心代码 #include <QMessageBox> #include <QFileDialog> #include <QDebug> #include <QProcess> #include <QDesktopServices> #include <QDateTime> #includ…

孙宇晨:区块链领域的坚韧领航者,以智慧铸就行业基石

​ 在区块链领域&#xff0c;孙宇晨以其卓越的智慧与不懈的韧性&#xff0c;成为行业内备受瞩目的领军人物。从创立波场 TRON 到引领去中心化的变革&#xff0c;孙宇晨始终以坚定的信念和独特的战略眼光推动着区块链技术的发展。 孙宇晨的成功不仅仅是因为他对技术的深入…

叉车驾驶员状态监控系统,司机身份安全识别,强化监管能力建设!

人脸识别技术作为人工智能领域的一个重要分支&#xff0c;已经广泛应用于安全识别、个人化推荐、社交网络等多个领域。其基于计算机视觉、图像处理、人脸检测、特征提取和人脸识别等先进技术&#xff0c;能够实现对人脸图像的精准分析和识别。在叉车驾驶场景中&#xff0c;AI人…

windows mfc webview2 接收html信息

webview2导入到mfc参考&#xff1a; windows vs2022 MFC使用webview2嵌入网页-CSDN博客 webview2与js交互参考&#xff1a;WebView2教程(基于C)【四】JS与C互访&#xff08;上&#xff09;_window.chrome.webview.postmessage-CSDN博客 一、JS端发送和接收 JS中&#xff0c;…

12代装win7影响性能吗?12代酷睿装win7关闭小核提高性能方法

12代酷睿装win7影响性能吗&#xff1f;12代酷睿装win7在性能上有点损耗&#xff0c;可以关闭小核提高性能。有些小朋友不知道怎么关闭上核来提高性能&#xff0c;下面电脑系统城小编就教大家12代酷睿装win7关闭核提高性能方法。 12代酷睿装win7说明&#xff1a;关闭小核解锁更多…

【分布式】分布式Session共享

这里通过SpringSession来实现Session的共享&#xff0c;Session数据存储在Redis中 SpringSession的操作指南&#xff1a; https://docs.spring.io/spring-session/docs/2.5.6/reference/html5/guides/boot-redis.html 导入相关的依赖 <dependency><groupId>org.s…

算法入门-递归3

第四部分&#xff1a;递归 143.重排链表&#xff08;中等&#xff09; 题目&#xff1a;给定一个单链表 L 的头节点 head &#xff0c;单链表 L 表示为&#xff1a; L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为&#xff1a; L0 → Ln → L1 → Ln - 1 → L2 → …

问题-小技巧-win11状态栏卡住

目前我只知道治标不治本的办法&#xff0c;打开任务管理器&#xff0c;找到Windows资源管理器右键重新启动&#xff0c;就可以解决这个问题。 这个问题我觉得是Win11自己的问题&#xff0c;等有新的发现&#xff0c;会进行补充。

使用Hutool工具类轻松生成验证码

效果图&#xff1a; 引入依赖&#xff1a; <!--hutool工具包--> <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.15</version> </dependency>核心代码 import cn.hutool.…

使用docker-compose运行kafka及验证(无需zookpeer)

前言&#xff1a;要求安装docker-compose kafka镜像版本&#xff1a;apache/kafka:3.8.0 可能存在镜像拉不下来的情况&#xff1a; 1、vim /etc/docker/daemon.json {"data-root":"/data/docker","registry-mirrors": ["https://docker.m…

高性价比百元蓝牙耳机如何选择?四款首选高性价比蓝牙耳机推荐

不知道什么时候开始&#xff0c;有线耳机悄悄的淡出了我们的视线。现在几乎都是蓝牙耳机首当前冲&#xff0c;因为比起有线耳机&#xff0c;蓝牙耳机更携带方便&#xff0c;拿出来就是秒连&#xff0c;体验感也不差。而且随着蓝牙耳机的价格不断下降&#xff0c;同时&#xff0…

【图文并茂】ant design pro 如何优雅奇妙地添加修改密码的功能

如上图所示&#xff0c;我们要加这样的一个功能&#xff0c;如何做呢&#xff1f; 首先要写好前端页面&#xff0c;再对接好后端&#xff0c;然后我们要判断当前密码是否正确&#xff0c;如果正确才能新密码修改好。 前端页面 src/pages/account/change-password/index.tsx …

【直观表格】常见神经网络计算复杂度对比 ——从时间复杂度和空间复杂度角度剖析

常见神经网络计算复杂度对比 ——从时间复杂度和空间复杂度角度剖析 【表格】常见神经网络计算复杂度对比 神经网络类型时间复杂度空间复杂度关键参数备注多层感知机&#xff08;MLP&#xff09; O ( n ⋅ d ⋅ h ) O(n \cdot d \cdot h) O(n⋅d⋅h) O ( d ⋅ h h ) O(d \c…

helm安装jenkins保姆级别

一、创建nfs服务器 这一步跳过、自行百度 注意&#xff1a;要给共享目录赋予权限chmod一下&#xff0c;不然到时候容器没办法在目录里面创建文件&#xff0c;初始化时候会报错误代码2 二、添加Jenkins的Helm仓库 helm repo add jenkinsci https://charts.jenkins.io helm re…

护眼台灯真的有用吗?学生护眼台灯十大牌子推荐

在当前近视患者剧增&#xff0c;我们发现近视还与青光眼的发生有关联&#xff0c;这是一种可能导致永久性视力丧失的眼病。青光眼通常是由于眼内压力过高造成的视神经损伤。高度近视患者的眼球结构变化可能增加眼压&#xff0c;从而提高患青光眼的风险。预防近视变得非常重要&a…

html js弹幕功能

效果如上 html <!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title><script charset"utf-8" src"https://unpkg.com/vue2.6.14/dist/vue.min.js" type"text/javascript">…

[C语言]-基础知识点梳理-编译、链接、预处理

前言 各位师傅大家好&#xff0c;我是qmx_07,今天来给大家讲解以下程序运行会经历哪些事情 翻译环境和运⾏环境 在ANSIC的任何⼀种实现中&#xff0c;存在两个不同的环境 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执⾏的机器指令&#xff08;⼆进制指令&a…

[FSCTF 2023]ez_php2

[FSCTF 2023]ez_php2 点开之后是一段php代码&#xff1a; <?php highlight_file(__file__); Class Rd{public $ending;public $cl;public $poc;public function __destruct(){echo "All matters have concluded";die($this->ending);}public function __call…

django宿舍管理系统 ---附源码98595

目 录 摘要 1 绪论 1.1 研究背景与意义 1.2 国内外研究现状 1.3论文结构与章节安排 2 宿舍管理系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析…

vue vite创建项目步骤

1. 创建vue项目 node版本需18以上 不然报错 npm init vuelatest2. 项目配置 配置项目的icon配置项目的标题配置jsconfig.json 3. 项目目录结构划分 4.css样式的重置 npm install normalize.cssreset.css html {line-height: 1.2; }body, h1, h2, h3, h4, ul, li {padding…