管道流设计模式结合业务

文章目录

    • 流程图
    • 代码实现
      • pom
      • context
        • EventContext
        • BizType
        • AbstractEventContext
      • filter
        • EventFilter
        • AbstractEventFilter
        • EventFilterChain
        • FilterChainPipeline
        • DefaultEventFilterChain
      • selector
        • FilterSelector
        • DefaultFilterSelector
    • 调用代码
      • PipelineApplication
      • controller
      • entity
      • service
      • service.business1
      • service.business1.context
      • service.business1.filters
      • service.business1.plugins
      • service.business2
      • service.business2.context
      • service.business2.filters
      • service.business2.plugins
      • service.config
      • service.selector
      • application.yml

流程图

请添加图片描述

代码实现

请添加图片描述

完整代码:https://gitee.com/gitee_pikaqiu/easy-pipeline

pom

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.plugin</groupId>
        <artifactId>spring-plugin-core</artifactId>
        <version>${spring.plugin.core.version}</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>${hutool.version}</version>
    </dependency>
</dependencies>

context

EventContext
public interface EventContext {


    /**
     * 是否继续调用链
     */
    boolean continueChain();


    /**
     * 获取当前过滤器选择器
     */
    FilterSelector getFilterSelector();

}
BizType
public interface BizType {


    /**
     * 获取业务类型码值
     */
    Integer getCode();

    /**
     * 业务类型名称
     *
     */
    String getName();

}
AbstractEventContext
public abstract class AbstractEventContext implements EventContext{


    private final BizType businessType;
    private final FilterSelector filterSelector;


    protected AbstractEventContext(BizType businessType, FilterSelector filterSelector) {
        this.businessType = businessType;
        this.filterSelector = filterSelector;
    }


    @Override
    public boolean continueChain() {
        return true;
    }

    @Override
    public FilterSelector getFilterSelector() {
        return filterSelector;
    }

}

filter

EventFilter
public interface EventFilter<T extends EventContext> {

    /**
     * 过滤逻辑封装点
     *
     * @param context 上下文对象
     * @param chain   调用链
     */
    void doFilter(T context, EventFilterChain<T> chain);

}
AbstractEventFilter
public abstract class AbstractEventFilter<T extends EventContext> implements EventFilter<T> {

    @Override
    public void doFilter(T context, EventFilterChain<T> chain) {
        // 执行
        if (context.getFilterSelector().matchFilter(this.getClass().getSimpleName())) {
            handler(context);
        }

        // 是否继续执行调用链
        if (context.continueChain()) {
            chain.nextHandler(context);
        }
    }


    /**
     * 执行器
     *
     * @param context 上下文对象
     */
    protected abstract void handler(T context);

}
EventFilterChain
public interface EventFilterChain<T extends EventContext> {


    /**
     * 执行当前过滤器
     *
     * @param context 上下文对象
     */
    void handler(T context);


    /**
     * 跳过当前过滤器 执行下一个执行过滤器
     *
     * @param context 上下文对象
     */
    void nextHandler(T context);

}
FilterChainPipeline
@Slf4j
@Component
public class FilterChainPipeline<F extends EventFilter>{


    private DefaultEventFilterChain<EventContext> last;


    public FilterChainPipeline<F> append(F filter){
        last = new DefaultEventFilterChain<>(last, filter);
        return this;
    }


    public FilterChainPipeline<F> append(String description, F filter){
        log.debug("过滤器调用链管道开始设置 {} 过滤器",description);
        last = new DefaultEventFilterChain<>(last, filter);
        return this;
    }


    public DefaultEventFilterChain<EventContext> getFilterChain() {
        return this.last;
    }

}
DefaultEventFilterChain
public class DefaultEventFilterChain<T extends EventContext> implements EventFilterChain<T> {

    private final EventFilterChain<T> next;
    private final EventFilter<T> filter;


    public DefaultEventFilterChain(EventFilterChain<T> next, EventFilter<T> filter) {
        this.next = next;
        this.filter = filter;
    }


    @Override
    public void handler(T context) {
        filter.doFilter(context,this);
    }

    @Override
    public void nextHandler(T context) {
        if (next != null) {
            next.handler(context);
        }
    }

}

selector

FilterSelector
public interface FilterSelector {


    /**
     * 匹配过滤器
     *
     * @param currentFilterName 过滤器名称
     * @return true 匹配成功
     */
    boolean matchFilter(String currentFilterName);

    /**
     * 获取当前所有过滤器名称
     *
     * @return 过滤器名称
     */
    List<String> getAllFilterNames();
}
DefaultFilterSelector
public class DefaultFilterSelector implements FilterSelector{

    @Setter
    private  List<String> filterNames = CollUtil.newArrayList();

    @Override
    public boolean matchFilter(String currentFilterName) {
        return filterNames.stream().anyMatch(s -> Objects.equals(s,currentFilterName));
    }


    @Override
    public List<String> getAllFilterNames() {
        return filterNames;
    }

}

调用代码

请添加图片描述

PipelineApplication

@SpringBootApplication
@EnablePluginRegistries(value = {Business1PostPlugin.class, Business2PostPlugin.class})
public class PipelineApplication {
    public static void main(String[] args) {
        SpringApplication.run(PipelineApplication.class, args);
    }
}

controller

@RestController
@RequestMapping("/pipelineTest")
public class PipelineController {

    @Autowired
    private Business1Service business1PipelineTestService;

    @Autowired
    private Business2Service business2PipelineTestService;


    @GetMapping("/business1")
    public void business1(){
        PipelineRequestVo pipelineTestRequest = new PipelineRequestVo();
        pipelineTestRequest.setUuid("business1-1110-1111231afsas-123adss");
        pipelineTestRequest.setBusinessCode("business1");
        pipelineTestRequest.setModel2(new Business1Model2());
        pipelineTestRequest.setModel1(new Business1Model1());
        business1PipelineTestService.doService(pipelineTestRequest);
    }


    @GetMapping("/business2")
    public void business2(){
        PipelineRequestVo pipelineTestRequest = new PipelineRequestVo();
        pipelineTestRequest.setUuid("business2-1110-1111231afsas-123adss");
        pipelineTestRequest.setBusinessCode("business2");
        pipelineTestRequest.setModel3(new Business2Model1());
        pipelineTestRequest.setModel4(new Business2Model2());
        business2PipelineTestService.doService(pipelineTestRequest);
    }

}

entity

@Data
public class PipelineRequestVo {


    private String uuid;

    private String businessCode;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business1Model1 model1;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business1Model2 model2;


    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business2Model1 model3;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business2Model2 model4;

}

service

@Getter
@AllArgsConstructor
public enum BusinessTypeEnum implements BizType {

    BUSINESS_1(1,"业务1"),
    BUSINESS_2(2,"业务2"),
    BUSINESS_3(3,"业务3"),
    ;



   private Integer code;
   private String name;

}

service.business1

public interface Business1Service {

    void doService(PipelineRequestVo pipelineTestRequest);
}
@Slf4j
@Service
public class Business1ServiceImpl implements Business1Service {

    @Qualifier("business1PipelineSelectorFactory")
    @Autowired
    private  PipelineSelectorFactory business1PipelineSelectorFactory;

    @Autowired
    private  FilterChainPipeline<Business1PipelineFilter> filterChainPipeline;

    @Autowired
    private  PluginRegistry<Business1PostPlugin, Business1Model1> business1PostPlugin;



    @Override
    public void doService(PipelineRequestVo pipelineTestRequest) {
        log.info("===============business1开始===============");
        // 处理器参数
        log.info("===============开始获取FilterSelector===============");
        FilterSelector filterSelector = business1PipelineSelectorFactory.getFilterSelector(pipelineTestRequest);
        Business1Context pipelineEventContext = new Business1Context(BusinessTypeEnum.BUSINESS_1, filterSelector);
        log.info("获取FilterSelector完成: {}",filterSelector.getAllFilterNames());
        log.info("===============获取FilterSelector完成===============");

        // 处理
        log.info("===============开始执行过滤器===============");
        pipelineEventContext.setPipelineTestRequest(pipelineTestRequest);
        pipelineEventContext.setModel2(pipelineTestRequest.getModel2());
        pipelineEventContext.setModel1(pipelineTestRequest.getModel1());
        filterChainPipeline.getFilterChain().handler(pipelineEventContext);
        log.info("===============执行过滤器完成===============");

        // 处理后获取值
        log.info("===============开始执行后置处理器===============");
        Business1Model2 model2 = pipelineEventContext.getModel2();
        Business1Model1 model1 = pipelineEventContext.getModel1();
        PipelineRequestVo pipelineTestRequest1 = pipelineEventContext.getPipelineTestRequest();
        business1PostPlugin.getPluginsFor(model1)
                .forEach(handler -> handler.postProcessing(model1));
        log.info("===============执行后置处理器完成===============");

        log.info("===============business1结束===============");

    }

}

service.business1.context

public class Business1Context extends AbstractEventContext {

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business1Model1 model1;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business1Model2 model2;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private PipelineRequestVo pipelineTestRequest;


    public Business1Context(BizType businessType, FilterSelector filterSelector) {
        super(businessType, filterSelector);
    }

    @Override
    public boolean continueChain() {
        return true;
    }

}
@Data
public class Business1Model1 {

    private Integer id;

    private String name1;

    private String name2;

    private String name3;

}
@Data
public class Business1Model2 {

    private Integer id;

    private String name;

    private String desc;

    private String age;

}

service.business1.filters

public interface Business1PipelineFilter extends EventFilter<Business1Context> {

    int order();
}
@Slf4j
@Component
public class Business1Filter1 extends AbstractEventFilter<Business1Context> implements Business1PipelineFilter {

    @Override
    public void handler(Business1Context context) {
        // 模拟操作数据库 等业务操作 可以利用门面模式进行解耦
        Business1Model1 model1 = context.getModel1();
        model1.setName1("张三");
        model1.setName2("李四");
        model1.setName3("王五");
        model1.setId(1);

        Business1Model2 model2 = context.getModel2();
        model2.setId(2);
        model2.setDesc("");
        model2.setAge("18");
        model2.setName("小白");

        log.info("Filter1执行完毕...");

        // 存入新的值到上下文对象中 下个处理器继续处理
        context.setModel1(model1);
        context.setModel2(model2);
    }

    @Override
    public int order() {
        return 1;
    }
}
@Slf4j
@Component
public class Business1Filter2 extends AbstractEventFilter<Business1Context>  implements Business1PipelineFilter {

    @Override
    public void handler(Business1Context context) {
        // 模拟操作数据库 等业务操作 可以利用门面模式进行解耦
        Business1Model1 model1 = context.getModel1();
        model1.setName1(model1.getName1() + "-------------");
        model1.setName2(model1.getName2() + "-------------");
        model1.setName3(model1.getName3() + "-------------");
        model1.setId(100);

        log.info("Filter2执行完毕...");
        // 存入新的值到上下文对象中 下个处理器继续处理
        context.setModel1(model1);
        context.setModel2(context.getModel2());
    }

    @Override
    public int order() {
        return 2;
    }
}

service.business1.plugins

public interface Business1PostPlugin extends Plugin<Business1Model1> {


    /**
     * 后置处理
     *
     * @param model 处理参数
     */
    void postProcessing(Business1Model1 model);

}
@Slf4j
@Component
public class Business1ServicePluginImpl implements Business1PostPlugin {


    @Override
    public boolean supports(Business1Model1 pipelineEventContext) {
        return true;
    }


    @Override
    public void postProcessing(Business1Model1 model) {
        log.info("===>{}",model.getId());
    }

}
@Slf4j
@Component
public class Business1ServicePluginImpl2 implements Business1PostPlugin {

    @Override
    public boolean supports(Business1Model1 model) {
        return true;
    }


    @Override
    public void postProcessing(Business1Model1 model) {
        log.info("===>{}",model.getId());
    }

}

service.business2

public interface Business2Service {

    void doService(PipelineRequestVo pipelineTestRequest);
}
@Slf4j
@Service
public class Business2ServiceImpl implements Business2Service {

    @Qualifier("business2PipelineSelectorFactory")
    @Autowired
    private PipelineSelectorFactory business2PipelineSelectorFactory;

    @Autowired
    private FilterChainPipeline<Business2PipelineFilter> filterChainPipeline;

    @Autowired
    private PluginRegistry<Business2PostPlugin, Business2Model1> business2PostPlugin;



    @Override
    public void doService(PipelineRequestVo pipelineTestRequest) {
        log.info("===============business2开始===============");
        // 处理器参数
        log.info("===============开始获取FilterSelector===============");
        FilterSelector filterSelector = business2PipelineSelectorFactory.getFilterSelector(pipelineTestRequest);
        Business2Context pipelineEventContext = new Business2Context(BusinessTypeEnum.BUSINESS_2, filterSelector);
        log.info("获取FilterSelector完成: {}",filterSelector.getAllFilterNames());
        log.info("===============获取FilterSelector完成===============");

        // 处理
        log.info("===============开始执行过滤器===============");
        pipelineEventContext.setPipelineTestRequest(pipelineTestRequest);
        pipelineEventContext.setModel2(pipelineTestRequest.getModel4());
        pipelineEventContext.setModel1(pipelineTestRequest.getModel3());
        filterChainPipeline.getFilterChain().handler(pipelineEventContext);
        log.info("===============执行过滤器完成===============");

        // 处理后获取值
        log.info("===============开始执行后置处理器===============");
        Business2Model2 model2 = pipelineEventContext.getModel2();
        Business2Model1 model1 = pipelineEventContext.getModel1();
        PipelineRequestVo pipelineTestRequest1 = pipelineEventContext.getPipelineTestRequest();
        business2PostPlugin.getPluginsFor(model1)
                .forEach(handler -> handler.postProcessing(model1));
        log.info("===============执行后置处理器完成===============");
        log.info("===============business2结束===============");
    }

}

service.business2.context

public class Business2Context extends AbstractEventContext {

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business2Model1 model1;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private Business2Model2 model2;

    /**
     * 在自定义的filter中处理
     */
    @Setter
    @Getter
    private PipelineRequestVo pipelineTestRequest;


    public Business2Context(BizType businessType, FilterSelector filterSelector) {
        super(businessType, filterSelector);
    }

    @Override
    public boolean continueChain() {
        return true;
    }

}
@Data
public class Business2Model1 {

    private Integer id;

    private String name1;

    private String name2;

    private String name3;

}
@Data
public class Business2Model2 {

    private Integer id;

    private String name;

    private String desc;

    private String age;

}

service.business2.filters

public interface Business2PipelineFilter extends EventFilter<Business2Context> {

     int order();
}
@Slf4j
@Component
public class Business2Filter1 extends AbstractEventFilter<Business2Context> implements Business2PipelineFilter {

    @Override
    public void handler(Business2Context context) {
        // 模拟操作数据库 等业务操作 可以利用门面模式进行解耦
        Business2Model1 model1 = context.getModel1();
        model1.setName1("张三");
        model1.setName2("李四");
        model1.setName3("王五");
        model1.setId(1);

        Business2Model2 model2 = context.getModel2();
        model2.setId(2);
        model2.setDesc("");
        model2.setAge("18");
        model2.setName("小白");

        log.info("Filter1执行完毕...");

        // 存入新的值到上下文对象中 下个处理器继续处理
        context.setModel1(model1);
        context.setModel2(model2);
    }

    @Override
    public int order() {
        return 1;
    }
}
@Slf4j
@Component
public class Business2Filter2 extends AbstractEventFilter<Business2Context>  implements Business2PipelineFilter {

    @Override
    public void handler(Business2Context context) {
        // 模拟操作数据库 等业务操作 可以利用门面模式进行解耦
        Business2Model1 model1 = context.getModel1();
        model1.setName1(model1.getName1() + "-------------");
        model1.setName2(model1.getName2() + "-------------");
        model1.setName3(model1.getName3() + "-------------");
        model1.setId(100);

        log.info("Filter2执行完毕...");
        // 存入新的值到上下文对象中 下个处理器继续处理
        context.setModel1(model1);
        context.setModel2(context.getModel2());
    }

    @Override
    public int order() {
        return 2;
    }
}

service.business2.plugins

public interface Business2PostPlugin extends Plugin<Business2Model1> {


    /**
     * 后置处理
     *
     * @param model 处理参数
     */
    void postProcessing(Business2Model1 model);

}
@Slf4j
@Component
public class Business2ServicePluginImpl implements Business2PostPlugin {


    @Override
    public boolean supports(Business2Model1 pipelineEventContext) {
        return true;
    }


    @Override
    public void postProcessing(Business2Model1 model) {
        log.info("===>{}",model.getId());
    }

}
@Slf4j
@Component
public class Business2ServicePluginImpl2 implements Business2PostPlugin {


    @Override
    public boolean supports(Business2Model1 model) {
        return true;
    }


    @Override
    public void postProcessing(Business2Model1 model) {
        log.info("===>{}",model.getId());
    }

}

service.config

@ConfigurationProperties(prefix = "test")
@Component
@Data
public class FilterConfigProperties {

    private Map<String, List<String>> configs;


    public Map<String, List<String>> getConfigs() {
        if (configs == null) {
            configs = MapUtil.newHashMap(16);
        }
        return configs;
    }

}
@Component
@RequiredArgsConstructor
public class PipelineFilterConfig {

    private final List<Business1PipelineFilter> business1PipelineFilter;
    private final FilterChainPipeline<Business1PipelineFilter> business1FilterChainPipeline;

    private final List<Business2PipelineFilter> business2PipelineFilter;
    private final FilterChainPipeline<Business2PipelineFilter> business2FilterChainPipeline;

    private final FilterConfigProperties filterConfigProperties;


    @Bean
    public FilterChainPipeline<Business1PipelineFilter> business1ChargePipeline() {
        Map<String, List<String>> configs = filterConfigProperties.getConfigs();
        if (business1PipelineFilter.isEmpty() || configs.isEmpty()){
            return business1FilterChainPipeline;
        }

        Set<Map.Entry<String, List<String>>> filtersName = configs.entrySet();
        long distinctCount = filtersName.stream().distinct().count();
        if (distinctCount > business1PipelineFilter.size()) {
            throw new IllegalArgumentException("设置的过滤器数量大于实际过滤器数量");
        }

        business1PipelineFilter
                .stream()
                .sorted(Comparator.comparing(Business1PipelineFilter::order))
                .forEach(business1FilterChainPipeline::append)
        ;
        return business1FilterChainPipeline;
    }


    @Bean
    public FilterChainPipeline<Business2PipelineFilter> business2ChargePipeline() {
        Map<String, List<String>> configs = filterConfigProperties.getConfigs();
        if (business2PipelineFilter.isEmpty() || configs.isEmpty()){
            return business2FilterChainPipeline;
        }

        Set<Map.Entry<String, List<String>>> filtersName = configs.entrySet();
        long distinctCount = filtersName.stream().distinct().count();
        if (distinctCount > business2PipelineFilter.size()) {
            throw new IllegalArgumentException("设置的过滤器数量大于实际过滤器数量");
        }

        business2PipelineFilter
                .stream()
                .sorted(Comparator.comparing(Business2PipelineFilter::order))
                .forEach(business2FilterChainPipeline::append)
        ;
        return business2FilterChainPipeline;
    }

}

service.selector

public interface PipelineSelectorFactory {
    FilterSelector  getFilterSelector(PipelineRequestVo request);
}
@Component("business1PipelineSelectorFactory")
public class Business1PipelineSelectorFactory implements PipelineSelectorFactory {

    @Autowired
    private FilterConfigProperties filterConfigProperties;

    @Override
    public FilterSelector getFilterSelector(PipelineRequestVo request) {
        String businessCode = request.getBusinessCode();
        DefaultFilterSelector defaultFilterSelector = new DefaultFilterSelector();
        if (businessCode.equals("business1")){
            defaultFilterSelector.setFilterNames(filterConfigProperties.getConfigs().getOrDefault(businessCode, Collections.unmodifiableList(new ArrayList<>())));
        }
        return defaultFilterSelector;
    }
}
@Component("business2PipelineSelectorFactory")
public class Business2PipelineSelectorFactory implements PipelineSelectorFactory {

    @Autowired
    private FilterConfigProperties filterConfigProperties;

    @Override
    public FilterSelector getFilterSelector(PipelineRequestVo request) {
        String businessCode = request.getBusinessCode();
        DefaultFilterSelector defaultFilterSelector = new DefaultFilterSelector();
        if (businessCode.equals("business2")){
            defaultFilterSelector.setFilterNames(filterConfigProperties.getConfigs().getOrDefault(businessCode, Collections.unmodifiableList(new ArrayList<>())));
        }
        return defaultFilterSelector;
    }

}

application.yml

server:
  port: 8080

test:
  configs:
    business1:
      - Business1Filter1
      - Business1Filter2
    business2:
      - Business2Filter1
      - Business2Filter2

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在C#中,PDFsharp库使用(三):PDF提取

PDF提取 一、PDF提取功能&#xff0c;看图 二、PDF提取界面 三、PDF提取代码 //pdf提取---选择文件Button private void button9_Click(object sender, EventArgs e) {string oneFilePath GetOneFilepath();if (!string.IsNullOrEmpty(oneFilePath)){textBox3.Text oneFilePa…

springboot汽车企业公司网站的系统设计ssm-java

框架&#xff1a;SSM/springboot都有 jdk版本&#xff1a;1.8 及以上 ide工具&#xff1a;IDEA 或者eclipse 数据库: mysql 编程语言: java 前端&#xff1a;layuibootstrapjsp 详细技术&#xff1a;HTMLCSSJSjspspringmvcmybatisMYSQLMAVENtomcat 开发工具 IntelliJ IDEA: 一…

带小数点的String类型数据,如何只取整数?

一、场景引入 如果前端页面存在列表展示用户数据&#xff0c;但是用户数据存在非常多的小数位&#xff0c;从页面来看&#xff0c;数据太多就会不太美观&#xff0c;因此&#xff0c;出于场景美化考虑&#xff0c;在不影响业务功能的情况下&#xff0c;可以只展示整数内容&…

00_Linux

文章目录 LinuxLinux操作系统的组成Linux的文件系统Linux操作系统中的文件类型Linux操作系统的组织结构 Linux vs WindowsNAT vs 桥接模式 vs 仅主机Linux Shell命令Linux⽂件与⽬录管理相关指令目录文件普通文件文本编辑 用户管理添加用户删除用户用户组管理 文件权限管理权限…

家庭营销广告Criteo公司首次获得MRC零售媒体测量认证

家庭营销广告Criteo公司首次获得零售媒体测量MRC认证 商业媒体公司Criteo2024年3月28日宣布&#xff0c;它首次获得媒体评级委员会&#xff08;MRC&#xff09;的认证&#xff0c;在其企业零售媒体平台commerce Max和commerce Yield上&#xff0c;在桌面、移动网络和移动应用内…

PCL SAC_IA配准高阶用法——统计每次迭代的配准误差并可视化

目录 一、概述二、代码实现三、可视化代码四、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、概述 在进行论文写作时,需要做对比实验,来分析改进算法的性能,期间用到了迭代误差分布统计的比较分析,为直…

mid_360建图和定位

录制数据 roslaunch livox_ros_driver2 msg_MID360.launch使用fast-lio 建图 https://github.com/hku-mars/FAST_LIO.git 建图效果 使用python做显示 https://gitee.com/linjiey11/mid360/blob/master/show_pcd.py 使用 point_lio建图 https://github.com/hku-mars/Point…

如何在C++的STL中巧妙运用std::find实现高效查找

如何在C的STL中巧妙运用std::find实现高效查找 一、简介二、在那里吗&#xff1f;2.1、在未排序的元素上2.2、已排序元素 三、在哪里?3.1、在未排序的元素上3.2、已排序元素 四、应该在哪里?五、结论 一、简介 本文章旨在涵盖所有在STL中&#xff08;甚至稍微超出&#xff0…

Eclipse 配置JDK版本,Eclipse Maven install 时使用的JDK版本

Eclipse配置JDK版本 Eclipse 配置JDK版本的地方&#xff1f; 在Eclipse中配置JDK版本的步骤如下&#xff1a; 打开Eclipse IDE。转到菜单栏并选择 “Window”&#xff08;窗口&#xff09;选项。在下拉菜单中选择 “Preferences”&#xff08;首选项&#xff09;&#xff0c;或…

asp.net core 依赖注入后的服务生命周期

ASP.NET Core 依赖注入&#xff08;DI&#xff09;容器支持三种服务的生命周期选项&#xff0c;它们定义了服务实例的创建和销毁的时机。理解这三种生命周期对于设计健壯且高效的应用程序非常重要&#xff1a; 瞬时&#xff08;Transient&#xff09;&#xff1a; 瞬时服务每次…

大型网站系统架构演化实例_3.使用服务集群改善网站并发处理能力

1.使用服务集群改善网站并发处理能力 使用集群是网站解决高并发、海量数据问题的常用手段。当一台服务器的处理能力、存储空间不足时&#xff0c;不要企图去更换更强大的服务器&#xff0c;对大型网站而言&#xff0c;不管多么强大的服务器&#xff0c;对大型网站而言&…

算法练习第20天|回溯算法 77.组合问题 257. 二叉树的所有路径

1.什么是回溯算法&#xff1f; 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。其本质是穷举&#xff0c;穷举所有可能&#xff0c;然后选出我们想要的答案。 2.为什么要有回溯算法? 那么既然回溯法并不高效为什么还要用它呢&#xff1f; 因为有的问题能暴力…

第10章 物理安全要求

10.1 站点与设施设计的安全原则 假如没有对物理环境的控制&#xff0c;任何管理的、技术的或逻辑的访问控制技术都无法提供足够的安全性。 如果怀有恶意的人员获取了对设施及设备的物理访问权&#xff0c;那么他们几乎可以为所欲为&#xff0c;包括肆意破坏或窃取、更改数据。…

光伏工程施工前踏勘方案与注意事项

光伏工程是指利用光能发电的技术。随着清洁能源的发展&#xff0c;光伏工程在能源领域的应用越来越广泛。在进行光伏工程施工前&#xff0c;需要对施工现场进行踏勘&#xff0c;以确保施工能够顺利进行并达到预期的效果。 本文游小编带大家一起看一下探勘的方案和注意事项。 1…

设计模式胡咧咧之策略工厂实现导入导出

策略模式&#xff08;Strategy Pattern&#xff09; 定义&#xff1a; 定义了一组算法&#xff0c;将每个算法都封装起来&#xff0c;并且使它们之间可以互换。 本质: 分离算法&#xff0c;选择实现 应用场景 何时使用 一个系统有许多类&#xff0c;而区分他们的只是他们直接…

【赛题】2024年“华中杯”数模竞赛赛题发布

2024年"华中杯"数学建模网络挑战赛——正式开赛&#xff01;&#xff01;&#xff01; 赛题已发布&#xff0c;后续无偿分享各题的解题思路、参考文献&#xff0c;帮助大家最快时间&#xff0c;选择最适合是自己的赛题。祝大家都能取得一个好成绩&#xff0c;加油&a…

Python数据可视化:散点图matplotlib.pyplot.scatter()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 Python数据可视化&#xff1a; 散点图 matplotlib.pyplot.scatter() 请问关于以下代码表述错误的选项是&#xff1f; import matplotlib.pyplot as plt x [1, 2, 3, 4, 5] y [2, 3, 5, 7,…

认识一下RAG

1.RAG技术背景与挑战 2.RAG的核心概念 3.RAG的工作流程与架构 4.RAG的优化方法 RAG的提出 •Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks是一篇重要的论文(2020年5月) •REALM: Retrieval-Augmented Language Model Pre-Training (2020)就将BERT预训练模…

libVLC Ubuntu编译详解

1.简介 有时候&#xff0c;windows上开发不满足项目需求&#xff0c;需要移植到linux上&#xff0c;不得不自行编译libvlc&#xff0c;编译libvlc相对而言稍微麻烦一点。 我使用的操作系统&#xff1a;Ubuntu20.04 查看系统命令lsb_release -a libvlc版本&#xff1a; 3.0.1…

CSS导读 (CSS的三大特性 上)

&#xff08;大家好&#xff0c;今天我们将继续来学习CSS的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 目录 五、CSS的三大特性 5.1 层叠性 5.2 继承性 5.2.1 行高的继承 5.3 优先级 小练习 五、CSS的三大特性 …