最新【Java万花筒】畅览实时数据的奇妙世界:Java库与框架应用指南,金三银四大厂面经总结

感受:

其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。

特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。

也祝愿各位同学,都能找到自己心动的offer。

分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档

拿到字节跳动offer后,简历被阿里捞了起来,二面迎来了P9"盘问"

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

    // 添加事件监听器
    statement.addListener((newData, oldData) -> {
        for (EventBean eventBean : newData) {
            String symbol = (String) eventBean.get("symbol");
            int totalQuantity = (int) eventBean.get("totalQuantity");
            System.out.println("Symbol: " + symbol + ", Total Quantity: " + totalQuantity);
        }
    });

    // 发送实时交易数据
    sendTradeData(service);

    // 等待查询结果
    try {
        Thread.sleep(60000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    // 关闭Esper引擎
    service.destroy();
}

private static void sendTradeData(EPServiceProvider service) {
    // 模拟发送实时交易数据
    EPRuntime runtime = service.getEPRuntime();

    Trade trade1 = new Trade("AAPL", "BUY", 100);
    Trade trade2 = new Trade("AAPL", "SELL", 50);
    Trade trade3 = new Trade("GOOG", "BUY", 200);
    Trade trade4 = new Trade("GOOG", "SELL", 150);

    runtime.sendEvent(trade1);
    runtime.sendEvent(trade2);
    runtime.sendEvent(trade3);
    runtime.sendEvent(trade4);
}

}

class Trade {
private String symbol;
private String action;
private int quantity;

public Trade(String symbol, String action, int quantity) {
    this.symbol = symbol;
    this.action = action;
    this.quantity = quantity;
}

// Getters and setters

}


以上示例代码演示了一个实时交易数据分析的场景,通过Esper引擎对交易数据进行处理和分析。代码中定义了一个Trade类作为事件数据的模型,使用Esper的EPL语言编写了一个查询语句,对交易数据的数量进行聚合,并按照股票代码进行分组。添加了一个事件监听器,当查询结果满足条件时会触发该监听器,并输出结果。


请注意,以上示例只是一个简单示例,实际使用时需要根据具体场景和业务需求进行相应的配置和开发。


##### 1.5 安装与配置


要使用Esper,首先需要进行安装和配置。以下是安装与配置Esper的步骤:


1. 下载Esper:可以从Esper官方网站(http://www.espertech.com/esper/)下载最新版本的Esper。
2. 解压文件:将下载的Esper压缩包解压到指定的目录。
3. 配置Esper:编辑解压后的目录下的`esper.yaml`文件,配置Esper的相关参数,如端口号、内存大小等。
4. 启动Esper:使用命令行进入Esper的安装目录,执行以下命令来启动Esper引擎:

 

java -jar esper.jar

5. 验证安装:在浏览器中访问`http://localhost:8080/`,如果能够正常访问Esper的管理控制台,则表示安装成功。


##### 1.6 EPL语法


Esper的核心特性是EPL(Event Processing Language),它是一种专门用于处理和查询事件流数据的语言。以下是一些常用的EPL语法和操作:


* `SELECT`:用于指定查询的输出字段。
* `FROM`:用于指定查询的事件源,可以是一个单独的事件流或多个事件流的组合。
* `WHERE`:用于指定查询的过滤条件,可以使用各种逻辑运算符和比较运算符。
* `GROUP BY`:用于指定查询的分组条件,可以按照某个或多个字段进行分组。
* `HAVING`:用于指定查询的聚合条件,可以对分组后的结果进行进一步筛选。
* `WINDOW`:用于定义窗口操作,可以是滑动窗口、事件时间窗口或基于事件属性的窗口。
* `JOIN`:用于将多个事件流进行关联,可以根据某个字段进行关联操作。
* `INSERT INTO`:用于将查询结果插入到新的事件流中。
* `DELETE FROM`:用于删除符合条件的事件。
* `UPDATE`:用于更新符合条件的事件。


以上只是EPL语言的一部分,Esper还提供了更多强大的语法和操作,能够满足复杂事件处理的需求。


##### 1.7 进阶应用


除了基本的查询和处理功能外,Esper还提供了一些进阶的应用功能:


* 实时数据分析:Esper可以对实时事件流数据进行即时分析和处理,帮助用户快速获取有用的信息和洞察。
* 预测和预警:Esper可以通过对事件流数据的分析和模式识别,提供预测和预警的功能,帮助用户及时做出决策。
* 机器学习和模型训练:Esper支持与机器学习库集成,可以进行实时数据的特征提取、模型训练和预测。
* 可视化和报表生成:Esper可以将分析结果可视化展示,并生成报表和图表,方便用户理解和分享分析结果。
* 分布式部署和扩展性:Esper可以在集群环境下部署,支持水平扩展和容错性,保证在大规模数据处理场景下的高可用性和性能。


Esper的应用领域非常广泛,可以应用于金融、物联网、市场营销等各个行业和领域。


以上就是Esper的简介、特性、示例代码和进阶应用内容,希望对你有所帮助。如果你有任何其他问题,请随时提问。


#### 2. Apache Flink


##### 2.1 简介


Apache Flink是一个快速、可靠的分布式流处理和批处理引擎。它提供了高效的数据处理方式,使开发人员能够处理实时数据流和批量数据,并具有低延迟、高可靠性和可伸缩性的特点。


##### 2.2 主要特性


* 流与批处理统一模型:Apache Flink提供了统一的编程模型,可以同时处理实时数据流和批量数据,无缝切换。
* 低延迟处理:Apache Flink采用了流式计算模型,能够在毫秒级别的延迟下处理大规模的实时数据。
* Exactly-Once语义:Apache Flink提供了Exactly-Once语义的处理保证,能够确保数据不被重复处理和丢失。
* 容错性和弹性扩展:Apache Flink具有容错性和弹性扩展的能力,可以在节点故障或数据倾斜的情况下保证数据处理的高可靠性和稳定性。


##### 2.3 应用场景


Apache Flink可以广泛应用于以下场景:


* 实时数据分析和处理:对实时数据流进行复杂的计算和分析,例如实时监控、实时统计分析等。
* 批量数据处理:对大规模批量数据进行高效的处理和分析,例如离线报表生成、离线数据清洗等。
* 事件驱动的应用程序:构建事件驱动的应用程序,例如实时预警系统、实时物联网应用等。


##### 2.4 Flink的流式处理示例


下面是一个使用Apache Flink进行流式处理的示例代码。假设我们有一个实时的交易数据流,每条交易数据包含交易时间、交易金额和交易类型。我们要统计每分钟的总交易金额,并将结果输出到日志文件中。



import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;

public class StreamingJob {
public static void main(String[] args) throws Exception {
// 设置执行环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

    // 创建交易数据流
    DataStream<Transaction> transactions = env
            .socketTextStream("localhost", 9999)
            .map(new MapFunction<String, Transaction>() {
                @Override
                public Transaction map(String value) throws Exception {
                    String[] fields = value.split(",");
                    long timestamp = Long.parseLong(fields[0]);
                    double amount = Double.parseDouble(fields[1]);
                    String type = fields[2];
                    return new Transaction(timestamp, amount, type);
                }
            });

    // 按照交易时间进行分组,并计算每分钟的总交易金额
    DataStream<TransactionAggregate> result = transactions
            .keyBy("timestamp")
            .timeWindow(Time.minutes(1))
            .sum("amount");

    // 将结果输出到日志文件
    result.print();

    // 执行任务
    env.execute("Streaming Job");
}

public static class Transaction {
    public long timestamp;
    public double amount;
    public String type;

    public Transaction(long timestamp, double amount, String type) {
        this.timestamp = timestamp;
        this.amount = amount;
        this.type = type;
    }
}

public static class TransactionAggregate {
    public long timestamp;
    public double sumAmount;

    public TransactionAggregate(long timestamp, double sumAmount) {
        this.timestamp = timestamp;
        this.sumAmount = sumAmount;
    }
}

}


上述代码中,我们使用`socketTextStream`方法创建了一个流数据源,实时从本地9999端口接收交易数据。然后使用`map`算子将每条交易数据映射为`Transaction`对象。接着,我们使用`keyBy`方法对交易数据按照交易时间进行分组,并使用`timeWindow`方法定义一个窗口,窗口的大小为1分钟。最后,使用`sum`算子对窗口内的交易金额进行求和。将结果输出到日志文件中。


##### 2.5 Flink的批处理示例


下面是一个使用Apache Flink进行批处理的示例代码。假设我们有一个包含大量文本文件的目录,我们要统计每个文件中包含特定关键词的行数,并将结果输出到控制台。



import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.util.Collector;

public class BatchJob {
public static void main(String[] args) throws Exception {
// 设置执行环境
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

    // 加载文本文件
    String inputPath = "path/to/text/files";
    DataSet<String> lines = env.readTextFile(inputPath);

    // 统计包含特定关键词的行数
    DataSet<Tuple2<String, Integer>> result = lines
            .flatMap(new Tokenizer())
            .groupBy(0)
            .sum(1);

    // 输出结果
    result.print();

    // 执行任务
    env.execute("Batch Job");
}

public static class Tokenizer implements FlatMapFunction<String, Tuple2<String, Integer>> {
    @Override
    public void flatMap(String value, Collector<Tuple2<String, Integer>> out) throws Exception {
        // 按空格分割每行文本,并输出(单词,1)的键值对
        String[] words = value.toLowerCase().split(" ");
        for (String word : words) {
            if (word.equals("keyword")) {
                out.collect(new Tuple2<>(word, 1));
            }
        }
    }
}

}


上述代码中,我们首先使用`readTextFile`方法加载文本文件,并将每一行作为一个字符串。然后,使用`flatMap`算子将每行文本按空格分割,并输出(单词,1)的键值对,其中只输出包含特定关键词的行。接着,使用`groupBy`方法将键值对按照单词进行分组,并使用`sum`算子对每个单词的频次进行求和。最后,将结果输出到控制台。


这是一个简单的批处理示例,您可以根据需要修改代码来适应不同的场景和需求。


以上是关于Apache Flink的简要介绍以及流式处理和批处理的示例代码。Apache Flink是一个功能强大的分布式数据处理引擎,具有广泛的应用场景和丰富的特性,可用于实时数据处理、批量数据处理和事件驱动的应用程序开发。


#### 3. Storm


##### 3.1 简介


Storm是一个开源的分布式实时计算系统,可以实时处理大规模的流式数据。它具有高性能、容错性和可扩展性的特点,适用于实时分析、实时监控和实时推荐等场景。


##### 3.2 主要特性


* 高性能:Storm采用多线程方式处理数据流,能够在毫秒级别的延迟下处理大规模的实时数据。
* 容错性和可伸缩性:Storm可以在节点故障的情况下保持数据处理的高可靠性,并能够弹性扩展以处理更多的数据流。
* 多语言支持:Storm支持多种编程语言,包括Java、Python和Scala等,使开发人员能够使用自己熟悉的语言开发和部署实时应用程序。



import org.apache.storm.Config;
import org.apache.storm.LocalCluster;
import org.apache.storm.topology.TopologyBuilder;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Values;
import org.apache.storm.utils.Utils;

public class WordCountTopology {
public static void main(String[] args) {
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout(“spout”, new RandomSentenceSpout(), 5);
builder.setBolt(“split”, new SplitSentenceBolt(), 8).shuffleGrouping(“spout”);
builder.setBolt(“count”, new WordCountBolt(), 12).fieldsGrouping(“split”, new Fields(“word”));

Config config = new Config();
config.setDebug(true);

LocalCluster cluster = new LocalCluster();
cluster.submitTopology("word-count", config, builder.createTopology());

Utils.sleep(10000);

cluster.killTopology("word-count");
cluster.shutdown();

}
}


##### 3.3 应用场景


Storm可以广泛应用于以下场景:


* 实时监控和告警:对实时数据进行监控和告警处理,例如网络监控、系统运行状态监控等。
* 实时推荐系统:根据用户的实时行为数据进行实时推荐,例如电商平台的个性化推荐、音乐平台的智能播放列表等。
* 日志处理:实时处理和分析大量的日志数据,例如日志实时分析、异常日志检测等。


##### 3.4 Storm示例代码


以下是一个使用Storm进行实时处理的示例代码。假设我们有一个随机产生句子的数据源,我们要对这些句子进行拆分,并统计每个单词的频次。



import org.apache.storm.Config;
import org.apache.storm.LocalCluster;
import org.apache.storm.topology.TopologyBuilder;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Tuple;
import org.apache.storm.tuple.Values;
import org.apache.storm.utils.Utils;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.base.BaseRichBolt;
import org.apache.storm.topology.base.BaseRichSpout;

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

public class WordCountTopology {
public static class RandomSentenceSpout extends BaseRichSpout {
private OutputCollector collector;
private Random random;
private String[] sentences;

    @Override
    public void open(Map config, TopologyContext context, OutputCollector collector) {
        this.collector = collector;
        this.random = new Random();
        this.sentences = new String[]{"I am happy", "You are sad", "He is angry"};
    }

    @Override
    public void nextTuple() {
        Utils.sleep(100);
        String sentence = sentences[random.nextInt(sentences.length)];
        collector.emit(new Values(sentence));
    }

    @Override
    public void declareOutputFields(org.apache.storm.topology.OutputFieldsDeclarer declarer) {
        declarer.declare(new Fields("sentence"));
    }
}

public static class SplitSentenceBolt extends BaseRichBolt {
    private OutputCollector collector;

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

    @Override
    public void execute(Tuple tuple) {
        String sentence = tuple.getStringByField("sentence");
        String[] words = sentence.split("\\s+");
        for (String word : words) {
            collector.emit(new Values(word));
        }
    }

    @Override
    public void declareOutputFields(org.apache.storm.topology.OutputFieldsDeclarer declarer) {
        declarer.declare(new Fields("word"));
    }
}

public static class WordCountBolt extends BaseRichBolt {
    private OutputCollector collector;
    private Map<String, Integer> wordCount;

    @Override
    public void prepare(Map config, TopologyContext context, OutputCollector collector) {
        this.collector = collector;
        this.wordCount = new HashMap<>();
    }

    @Override
    public void execute(Tuple tuple) {
        String word = tuple.getStringByField("word");
        int count = wordCount.getOrDefault(word, 0) + 1;
        wordCount.put(word, count);
        collector.ack(tuple);
        if (count >= 5) {
            System.out.println("Word: " + word + ", Count: " + count);
        }
    }

    @Override
    public void declareOutputFields(org.apache.storm.topology.OutputFieldsDeclarer declarer) {

    }
}

public static void main(String[] args) throws InterruptedException {
    TopologyBuilder builder = new TopologyBuilder();
    builder.setSpout("spout", new RandomSentenceSpout(), 1);
    builder.setBolt("split", new SplitSentenceBolt(), 1).shuffleGrouping("spout");
    builder.setBolt("count", new WordCountBolt(), 1).fieldsGrouping("split", new Fields("word"));

    Config config = new Config();
    config.setDebug(false);

    LocalCluster cluster = new LocalCluster();
    cluster.submitTopology("word-count", config, builder.createTopology());

    Thread.sleep(10000);

    cluster.killTopology("word-count");
    cluster.shutdown();
}

}


在这个示例中,我们定义了三个组件:`RandomSentenceSpout`,`SplitSentenceBolt`和`WordCountBolt`。


`RandomSentenceSpout`是一个数据源,随机产生句子,并将其发送给下一个组件`SplitSentenceBolt`。


`SplitSentenceBolt`对接收到的句子进行拆分,并将每个单词发送给`WordCountBolt`。


`WordCountBolt`接收单词并进行频次统计,如果某个单词的频次达到5次,就输出到控制台。


**Java面试核心知识点笔记**

其中囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。

![蚂蚁金服(Java研发岗),26岁小伙斩获三面,收获Offer定级P6](https://img-blog.csdnimg.cn/img_convert/7062ba0b00954d54dcae6b496ea378a9.webp?x-oss-process=image/format,png)

**Java中高级面试高频考点整理**

![蚂蚁金服(Java研发岗),26岁小伙斩获三面,收获Offer定级P6](https://img-blog.csdnimg.cn/img_convert/caa41da7d658d50554d31b3317ecec1b.webp?x-oss-process=image/format,png)

![蚂蚁金服(Java研发岗),26岁小伙斩获三面,收获Offer定级P6](https://img-blog.csdnimg.cn/img_convert/1a7fcf8204b192bfd79dd5855be2d2ab.webp?x-oss-process=image/format,png)

**最后分享Java进阶学习及面试必备的视频教学**

![蚂蚁金服(Java研发岗),26岁小伙斩获三面,收获Offer定级P6](https://img-blog.csdnimg.cn/img_convert/b2a6f7e5d8eea2b53365eceee08992dd.webp?x-oss-process=image/format,png)


> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。

[外链图片转存中...(img-CK49JHtc-1715653847142)]

**Java中高级面试高频考点整理**

[外链图片转存中...(img-dSIUWPji-1715653847142)]

[外链图片转存中...(img-bwMozN0b-1715653847142)]

**最后分享Java进阶学习及面试必备的视频教学**

[外链图片转存中...(img-18ZtvJoO-1715653847143)]


> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值