storm计数器(小白看懂系列)

2023-11-07

现在要用storm做一个计数器,我的方案是:不断地输入一串字符串,然后统计每个单词的频数.

这篇博客从以下几个方面进行阐述:

  1. 基本配置
  2. 流程分析与类的确定
  3. 奉上代码(含注释)
一:基本配置
这里注意,导包的时候要注意,否则可能会出现神奇的强制类型转换或是提示你在使用一个不存在的方法
  • 三台搭建好storm集群的linux虚拟机centos7
  • 一台用于编程的window8.1虚拟机
  • 这三台虚拟机使用桥接模式,即与宿主机在同一个网络中
二.流程分析与类的确定
  • TopologyWordCount ------用于构建整个逻辑拓扑,是整个storm的核心
  • CreateSpout ------源源不断的创建原始字符串
  • SplitBolt ------把原始字符串分割为单词后,把每个单词发送出去
  • CountBolt ------对传来的单词进行频数记录
  • PrintBolt ------把所有结果进行打印

注:既然可以源源不断的创建字符串,那么PrintBolt要打印结果就需要有一个时间限制,在这里,设定10s打印一次.
三.奉上代码
先奉上pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>storm</groupId>
    <artifactId>storm</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--上面的按照你自己的项目来就好,修改下面的内容就可以了-->
    <properties>
        <jstorm.version>2.1.1</jstorm.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <slf4j.version>1.7.12</slf4j.version>
        <joad-time.version>2.9.4</joad-time.version>
        <storm-kafka.version>0.9.4</storm-kafka.version>
        <kafka.version>0.9.0.0</kafka.version>
        <esper.version>5.4.0</esper.version>
    </properties>

    <dependencies>


        <!-- https://mvnrepository.com/artifact/com.espertech/esper -->


        <!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>${joad-time.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka_2.11 -->
        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka_2.11</artifactId>
            <version>${kafka.version}</version>
            <scope>provided</scope>
        </dependency>


        <dependency>
            <groupId>com.alibaba.jstorm</groupId>
            <artifactId>jstorm-core</artifactId>
            <version>${jstorm.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.storm/storm-kafka -->
        <dependency>
            <groupId>org.apache.storm</groupId>
            <artifactId>storm-kafka</artifactId>
            <version>${storm-kafka.version}</version>
        </dependency>


        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jdk14</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>${slf4j.version}</version>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>TopologyWordCount.java</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-my-jar-with-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>


  • TopologyWordCount 用于构建整个逻辑拓扑,是整个storm的核心
import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.StormSubmitter;
import backtype.storm.generated.AlreadyAliveException;
import backtype.storm.generated.InvalidTopologyException;
import backtype.storm.topology.TopologyBuilder;
import backtype.storm.tuple.Fields;

public class TopologyWordCount {
    public static void main(String[] args) throws AlreadyAliveException, InvalidTopologyException, InterruptedException {
        TopologyBuilder builder = new TopologyBuilder();

        //设置数据源
        builder.setSpout("spout", new CreateSpout(), 1);
        //读取spout的数据源,完成切分字符串的操作
        builder.setBolt("split", new SplitBolt(), 1).shuffleGrouping("spout");
        //读取split后的数据,进行count(tick周期10秒)
        builder.setBolt("count", new CountBolt(), 1).fieldsGrouping("split", new Fields("word"));
        //读取show之后的缓冲后的数据,进行最终的打印
        builder.setBolt("final", new PrintBolt(), 1).shuffleGrouping("count");


        /*---------------套路--------------------*/
        Config config = new Config();
        config.setDebug(false);
        //集群模式
        if (args != null && args.length > 0) {
            config.setNumWorkers(2);
            StormSubmitter.submitTopology(args[0], config, builder.createTopology());
            //单机模式
        } else {
            config.setMaxTaskParallelism(1);
            LocalCluster cluster = new LocalCluster();
            cluster.submitTopology("word-count", config, builder.createTopology());
            Thread.sleep(3000000);
            cluster.shutdown();
        }
    }
}
这里定义了整个拓扑结构,在学习时可能 .shuffleGrouping() 这种函数不太明白,这个叫做storm的分组策略,现在讲解太细致不太好,因此我用下面的这个图简单的告诉大家大致的含义:
在这里,那个.shuffleGrouping()传入的参数就表明它要接收的数据是来自哪个Bolt 或是Spout
  • CreateSpout 源源不断的创建原始字符串
import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichSpout;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Values;
import backtype.storm.utils.Utils;
import org.joda.time.DateTime;

import java.util.Map;

/**
 * 创建数据
 */
public class CreateSpout extends BaseRichSpout {

    private SpoutOutputCollector collector;
    private String[] sentences = null; //用来存放数据


    @Override
    public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
        this.collector = spoutOutputCollector;
        sentences = new String[]{"Hahahaha! I am coming ~~"}; // "Hahaha...这个字符串即为要源源不断发送的信息"
    }

    @Override
    public void nextTuple() {
        /*storm会循环的调用这个方法*/
        /*线程进行休眠,10s发送一次数据,在这10s内,让其余工作进行*/
        Utils.sleep(10000);
        //获得数据源
        System.out.println(new DateTime().toString("HH:mm:ss") + "--------------CreateSpout 开始发送数据----------");
        this.collector.emit(new Values(sentences)); //发送出去
    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
//发送时设置接收方的Tuple实例中的key
        outputFieldsDeclarer.declare(new Fields("sentence"));
    }

}


这里为什么要休眠10s,就是为了让整个流程每10s执行一遍,否则很难看清楚整个流程是如何执行的.

  • SplitBolt 把原始字符串分割为单词后,把每个单词发送出去
import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values;
import org.joda.time.DateTime;

import java.util.Map;

/**
 * 按照空格切分字符串,然后推出去
 */
public class SplitBolt extends BaseRichBolt {

    private OutputCollector outputCollector;
    private int countTime = 0;

    @Override
    public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
        this.outputCollector = collector;
    }

    @Override
    public void execute(Tuple tuple) {
        /*这是官方文档中 tuple.getString(int i)的解释:
          Returns the String at position i in the tuple. If that field is not a String, you will get a runtime error.
                public String getString ( int i);
         */
        String sentence = tuple.getString(0);
        for (String word : sentence.split(" ")) {
            System.out.println(new DateTime().toString("HH:mm:ss") + "--------------------SplitBolt 开始运行--------------------\n" + "> > > >  第"+count() +"次发送数据,这次发送的是:" + word);
            outputCollector.emit(new Values(word));
        }
    }
    //这是为了得到当前一共发送了多少个单词了,加深理解
    private int count() {
        return ++countTime;
    }

    /*在发射的时候,将接收方的tuple中的 key 设置为"word"*/
    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        declarer.declare(new Fields("word"));
    }
}
  • CountBolt 对传来的单词进行频数记录
import backtype.storm.Config;
import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values;
import backtype.storm.utils.TupleHelpers;
import org.joda.time.DateTime;

import java.util.HashMap;
import java.util.Map;

public class CountBolt extends BaseRichBolt {

    private Map<String, Integer> counts = new HashMap<>();
    private OutputCollector outputCollector;


    @Override
    public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
        this.outputCollector = collector;
    }

    @Override
    public Map<String, Object> getComponentConfiguration() {
        Map<String, Object> conf = new HashMap<String, Object>();
        /*加入Tick时间窗口, 统计*/
        /*------------------?????????????????????????---------------------------*/
        conf.put(Config.TOPOLOGY_TICK_TUPLE_FREQ_SECS, 10);
        return conf;
    }

    @Override
    public void execute(Tuple tuple) {
        /*时间窗口定义为10s内的统计数据,统计完毕后,发射到下一阶段的bolt进行处理*/
        //发射完成后return结束,开始新一轮的事件窗口计数操作
        if (TupleHelpers.isTickTuple(tuple)) {/*来判断是否应该发射当前窗口数据*/
            System.out.println((new DateTime().toString("HH:mm:ss")) + "--------------------sumWordBolt 开始运行--------------------\n发送的数据内容是" + counts);
            outputCollector.emit(new Values(counts));
            return;
        }

        /*如果没有到发送时间,就继续统计wordcount*/
        String word = tuple.getStringByField("word");
        Integer count = counts.get(word);
        if (count == null) {
            count = 0;
        }
        count++;
        counts.put(word, count);
    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        declarer.declare(new Fields("word_map"));
    }
}
  • PrintBolt 把所有结果进行打印
import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.tuple.Tuple;
import org.joda.time.DateTime;

import java.util.Map;

public class PrintBolt extends BaseRichBolt {
    @Override
    public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
    }

    @Override
    public void execute(Tuple input) {
        System.out.println(new DateTime().toString("HH:mm:ss") + "--------------------final bolt 开始运行--------------------");
        /*----------???????????????????????---------------------------*/
        Map<String, Integer> counts = (Map<String, Integer>) input.getValue(0);
        /*最后一个阶段,将最后的结果打印出来*/
        System.out.println(justForm(20-8)+"key"+justForm(20-8)+"      "+"value");
        for (Map.Entry<String, Integer> kv : counts.entrySet()) {
            /*这里的justForm()函数是为了保证格式一致*/
            System.out.println(kv.getKey() + justForm(kv.getKey().length()) + " 频数 : " + kv.getValue());
        }
    }
	
	//保证格式一致的私有方法
    private String justForm(int length) {
        for (int i = 0; i < 20 - length; i++) {
            System.out.print(" ");
        }
        return "";
    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
    }
}


在这里,如果有谜一般的强制类型转换,或是方法上的报错,估计是导包的时候错了,认真检查一下是不是导包导错了
运行之后的效果图可以帮助你理解整个storm的流程:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

storm计数器(小白看懂系列) 的相关文章

  • Spark 中 BroadCast 导致的内存溢出(SparkFatalException)

    背景 本文基于 Spark 3 1 1 open jdk 1 8 0 352 目前在排查 Spark 任务的时候 遇到了一个很奇怪的问题 在此记录一下 现象描述 一个 Spark Application Driver端的内存为 5GB 一直
  • AI大模型应用入门实战与进阶:深入理解Transformer架构

    1 背景介绍 自从2017年的 Attention is All You Need 一文发表以来 Transformer架构已经成为自然语言处理 NLP 领域的主流模型 这篇文章将深入探讨Transformer架构的核心概念 算法原理以及实
  • 慢思维大脑:SOP流程的心理学背景

    1 背景介绍 慢思维大脑 SOP流程的心理学背景 慢思维是指人类大脑在处理复杂问题 做出重要决策时所采用的思考方式 它与快速 自动的快思维相对 主要通过以下几种方式表现 深入思考 慢思维会让人类大脑深入思考问题的本质 从而找出更深层次的解决
  • AI大模型应用入门实战与进阶:如何训练自己的AI模型

    1 背景介绍 人工智能 Artificial Intelligence AI 是计算机科学的一个分支 旨在模拟人类智能的能力 包括学习 理解自然语言 识别图像和视频 进行决策等 随着数据量的增加和计算能力的提升 人工智能技术的发展得到了巨大
  • 机器智能与人类智能的竞争:技术创新的驱动力

    1 背景介绍 人工智能 Artificial Intelligence AI 和机器学习 Machine Learning ML 是最近几年最热门的技术领域之一 随着数据量的增加和计算能力的提高 机器学习技术的发展得到了极大的推动 机器学习
  • 技术管理者的核心能力在哪?

    作为管理者我曾经被下属当面问过 你为什么不写代码 诚然 我最近两年 代码越写越少 会越开越多 但 存在真的合理吗 我的核心能力应该是什么 看了一篇文章 它提出一个观点 技术管理者的核心能力在于技术判断力 通过在技术领域和非技术领域的长期积累
  • 【CTF必看】从零开始的CTF学习路线(超详细),让你从小白进阶成大神!

    最近很多朋友在后台私信我 问应该怎么入门CTF 个人认为入门CTF之前大家应该先了解到底 什么是CTF 而你 学CTF的目的又到底是什么 其次便是最好具备相应的编程能力 若是完全不具备这些能力极有可能直接被劝退 毕竟比赛的时候动不动写个脚本
  • Web 安全漏洞之 OS 命令注入

    什么是 OS 命令注入 上周我们分享了一篇 Web 安全漏洞之 SQL 注入 其原理简单来说就是因为 SQL 是一种结构化字符串语言 攻击者利用可以随意构造语句的漏洞构造了开发者意料之外的语句 而今天要讲的 OS 命令注入其实原理和 SQL
  • 5个步骤,教你瞬间明白线程和线程安全

    记得今年3月份刚来杭州面试的时候 有一家公司的技术总监问了我这样一个问题 你来说说有哪些线程安全的类 我心里一想 这我早都背好了 稀里哗啦说了一大堆 他又接着问 那你再来说说什么是线程安全 然后我就GG了 说真的 我们整天说线程安全 但是对
  • WEB前端常见受攻击方式及解决办法总结

    一个网址建立后 如果不注意安全问题 就很容易被人攻击 下面讨论一下集中漏洞情况和放置攻击的方法 一 SQL注入 所谓的SQL注入 就是通过把SQL命令插入到web表单提交或输入域名或页面请求的查询字符串 最终达到欺骗服务器执行恶意的SQL命
  • 用户数据中的幸存者偏差

    幸存者偏差 Survivorship bias 是一种常见的逻辑谬误 意思是没有考虑到筛选的过程 忽略了被筛选掉的关键信息 只看到经过筛选后而产生的结果 先讲个故事 二战时 无奈德国空防强大 盟军战机损毁严重 于是军方便找来科学家统计飞机受
  • 2024年华数杯国际赛B题:光伏发电功率 思路模型代码解析

    2024年华数杯国际赛B题 光伏发电功率 Photovoltaic Power 一 问题描述 中国的电力构成包括传统能源发电 如煤 油和天然气 可再生能源发电 如水电 风能 太阳能和核能 以及其他形式的电力 这些发电模式在满足中国对电力的巨
  • 2024年金三银四网络安全考试试题

    2023年金三银四网络安全考试试题 1 关于数据使用说法错误的是 A 在知识分享 案例中如涉及客户网络数据 应取敏感化 不得直接使用 B 在公开场合 公共媒体等谈论 传播或发布客户网络中的数据 需获得客户书面授权或取敏感化 公开渠道获得的除
  • 基于java的物业管理系统设计与实现

    基于java的物业管理系统设计与实现 I 引言 A 研究背景和动机 物业管理系统是指对物业进行管理和服务的系统 该系统需要具备对物业信息 人员信息 财务信息等进行管理的能力 基于Java的物业管理系统设计与实现的研究背景和动机主要体现在以下
  • 扬帆证券:突发利好!外资重大转变,A股收到多份喜报

    A股财报季 利好音讯密集传来 1月16日晚间 A股多家上市公司披露了成绩预告 其间成绩预增 扭亏等利好公告数量占比超80 其间 普瑞眼科公告 估计2023年净赢利同比添加高达1163 98 1285 51 别的 多家上市公司公告称 估计20
  • 国外拨号VPS指南:开启你的全球网络之旅

    在当今数字化时代 互联网已经成为了我们生活的一部分 而要在全球范围内畅通无阻地访问互联网 拥有一个可靠的国外拨号VPS是非常重要的 无论您是为了工作 学习还是娱乐 国外拨号VPS都可以为您提供更广泛的网络体验 本文将为您提供国外拨号VPS的
  • CorelDRAW2024官方中文版重磅发布更新

    35年专注于矢量设计始于1988年并不断推陈出新 致力为全球设计工作者提供更高效的设计工具 CorelDRAW 滋养并见证了一代设计师的成长 在最短的时间内交付作品 CorelDRAW的智能高效会让你一见钟情 CorelDRAW 全称 Co
  • 静态综合实验

    1 IP地址划分 192 168 1 0 27 用于主干拆分 192 168 1 32 27 用于用户拆分 192 168 1 64 27 用于用户拆分 192 168 1 96 27 用于用户拆分 192 168 1 128 27 用于用
  • ESM10A 消除对单独 PLC 的需求

    ESM10A 消除对单独 PLC 的需求 ESM10A 可以消除对单独 PLC 的需求 该程序是在 PC 上开发的 然后使用免费提供的简单易用的 EzSQ 软件下载到逆变器 似乎这些改进还不够 日立还在 SJ700 中添加了其他新功能 例如
  • ESP10B 锁定连接器

    ESP10B 锁定连接器 ESP10B 电机新增内容包括双极型号标准 NEMA 尺寸 17 23 和 34 的步进电机现在包括输出扭矩范围从 61 盎司英寸到 1291 盎司英寸的双极型号 该电机配有带锁定连接器的尾缆 可轻松连接 每转可步

随机推荐

  • 云计算和物联网之间是什么关系,主要有什么区别?

    云计算和物联网是当今IT业界的两大焦点 它们有很大的区别 但同时也有着千丝万缕的联系 物联网通过数量惊人的传感器采集到难以计数的数据量 而云计算可以对这些海量数据进行智能处理 云计算是物联网发展的基石 而物联网又是云计算的最大用户 促进着云
  • Charles乱码和SSL 代理问题解决

    在刚接触Charles进行抓包使用时 遇到了两个问题 1 Charles上抓的包出现了乱码 2 Charles开启SSL Proxying代理后出现了手机无法上网或手机和电脑浏览器都无法上网的情况 浏览器提示证书不可用或过期 尝试了很久终于
  • SpringBoot开启事务

    Java知识点总结 想看的可以从这里进入 目录 2 12 事务开启 2 12 事务开启 Spring Boot使用的是Spring 事务管理机制 对事务管理提供了一个顶层的接口PlatformTransactionManager 对所支持的
  • RPA让采购流程更加高效丨采购领域应用RPA的5大场景

    采购是企业生产经营中必不可少的环节之一 也是企业成本构成的主要因素 企业采购形式多样 包括招标 竞争性谈判 磋商 询价 竞价等 如今 互联网的发展已经升级了采购模式 借力RPA提升采购效率 则是企业确保供应 降低成本 实现可持续发展的一个良
  • 深度学习实战(四):行人跟踪与摔倒检测报警

    深度学习实战 四 行人跟踪与摔倒检测报警 1 项目简介 1 1 相关工作 2 方法简介 2 1 总体结构 2 2 骨架的图结构 2 3 空间图卷积网络 2 3 1 Sampling Function 2 3 2 Weight Functio
  • 大修或新更换的电压互感器TV为什么要核相(定相)?

    大修或新更换的电压互感器TV为什么要核相 定相 答 大修或新更换的互感器 含二次回路更动 在投入运行前应核相 定相 所谓定相 就是将TV一次侧在同一电源上 测定它们的二次侧电压相位是否相同 若相位不正确 会造成如下结果 1 破坏同期的正确性
  • [JSOI2018]机器人

    题目描述 一个 n m n times m n m的网格 有一个机器人一开始在 1 1
  • 画图软件怎么做性能测试,软件性能测试能力提升解决方案.pdf

    软件性能测试能力提升解决方案 软件性能测试能力提升解决方案 软件性能测试能力提升解决方案 软软件件性性能能测测试试能能力力提提升升解解决决方方案案 课程试用 课程试用 课课程程试试用用 测试经理 TM 测试主测 TC 测试架构师 TAE 测
  • ChatGPT充值,银行卡被拒绝,图文教程

    目录 前言 步骤 1 魔法地址选择 2 选择手机号码 归属地 3 勾选 服从协议 4 填写信息 5 完善账单地址 6 订阅成功 前言 大家好 今天我在订阅ChatGPT4时 遭遇了银行卡被拒绝的尴尬境地 这里有个技巧 助你开心畅享ChatG
  • 大数据和人工智能的关系,超全解析

    大数据拥抱云计算 在PaaS层中一个复杂的通用应用就是大数据平台 大数据是如何一步一步融入云计算的呢 1数据不大也包含智慧 一开始这个大数据并不大 原来才有多少数据 现在大家都去看电子书 上网看新闻了 在我们80后小时候 信息量没有那么大
  • 使用C++封装MySQL API的教程(Python)

    在本教程中 我们将学习如何使用C 封装MySQL的API 并使用Python作为示例 我们将创建一个简单的程序 通过C 封装的MySQL API连接到MySQL数据库 并执行一些基本的数据库操作 MySQL是一个流行的开源关系型数据库管理系
  • ESP32(MicroPython)LVGL图形界面 RGB灯闪烁控制器

    ESP32 MicroPython RGB灯闪烁控制器 本程序通过依次调整RGB灯中每个灯的P 频率和占空比实现对RGB灯闪烁的控制 import lvgl as lv import time from espidf import VSPI
  • 【Shell牛客刷题系列】SHELL10 第二列是否有重复:复习sort命令和uniq命令~

    该系列是基于牛客Shell题库 针对具体题目进行查漏补缺 学习相应的命令 刷题链接 牛客题霸 Shell篇 该系列文章都放到专栏下 专栏链接为 专栏 Linux 欢迎关注专栏 本文知识预告 本文主要涉及的命令是sort命令和uniq命令 这
  • Python_inspect的使用

    The inspect module provides several useful functions to help get information about live objects such as modules classes
  • Kafka基础知识(个人总结)

    声明 1 本文为我的个人复习总结 并非那种从零基础开始普及知识 内容详细全面 言辞官方的文章 2 由于是个人总结 所以用最精简的话语来写文章 3 若有错误不当之处 请指出 消息队列 作用 优点 异步处理 使用微信 进行建行卡支付时 如果没资
  • 每日一题分享(三)

    给你一个含 n 个整数的数组 nums 其中 nums i 在区间 1 n 内 请你找出所有在 1 n 范围内但没有出现在 nums 中的数字 并以数组的形式返回结果 分析 第一种思路 1 我们可以新定义一个数组 里面放的就是1到n的数 2
  • (二十一)QT的构造函数重载

    在实际开发中 我们可能遇到一个问题 对于一个类 我们可能需要传递给它不同的参数 让它执行不同的行为 或者在使用旧的类时 我们希望加上一个新的参数 但是这个参数在旧的逻辑中不使用 需要在新的逻辑中使用 如果我们改了这个类 会导致使用旧的类的函
  • 打造高质量视频,创造视觉奇观!Camtasia 2023为你升级!

    嘿 伙计 在这个全新版本中 我们迎来了焕然一新的动画控制和更简化的特效制作流程 让创作变得更高效 不仅如此 全新的背景去除和动画光标功能也让视频拥有全新的视觉体验 让我们先谈谈光标 这个细节或许被忽视 却能让您的录屏更显个性 Camtasi
  • OSI七层网络结构图与TCP/IP五层网络结构图

    一 OSI七层网络结构图与TCP IP五层网络结构图 又称 OSI七层网络模型与TCP IP四层网络模型 1 OSI七层模型 OSI中的层 功能 TCP IP协议族 应用层 文件传输 电子邮件 文件服务 虚拟终端 TFTP HTTP SNM
  • storm计数器(小白看懂系列)

    现在要用storm做一个计数器 我的方案是 不断地输入一串字符串 然后统计每个单词的频数 这篇博客从以下几个方面进行阐述 基本配置 流程分析与类的确定 奉上代码 含注释 一 基本配置 这里注意 导包的时候要注意 否则可能会出现神奇的强制类型