携程面试:100 亿分库分表 如何设计? 核弹级 16字真经, 让面试官彻底 “沦陷”,当场发offer!

简介: 携程面试:100 亿分库分表 如何设计? 核弹级 16字真经, 让面试官彻底 “沦陷”,当场发offer!

本文的 原始地址 ,传送门

本文的 原始地址 ,传送门

说在前面

在45岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题::

  • 尼恩老师,面试官问我有一个订单表。有商品类别,订单id用户id,运营id,数据量上百亿这种情况,要有能对商品类别进行查询,运营查询他负责的跟单信息,按照订单号查询用户查询对应订单。要怎么去设计数据库的存储结构?
  • 100亿数据海量数据,如何进行存储架构?

最近有小伙伴在面试 携程,又遇到了相关的面试题。小伙伴懵了,因为没有遇到过,所以支支吾吾的说了几句,面试官不满意,面试挂了。

所以,尼恩给大家做一下系统化、体系化的梳理,使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

当然,这道面试题,以及参考答案,也会收入咱们的 《尼恩Java面试宝典PDF》V171版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

最新《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请关注本公众号【技术自由圈】获取,回复:领电子书

100亿数据海量数据 架构的16字设计原则 :

100亿数据海量数据 架构,尼恩给大家梳理一个 16字设计原则 :

  • 冷热分离‌:以访问频率驱动存储成本优化

  • 强弱解耦‌:以业务重要性划分一致性等级

  • 冗余双写‌:以查询需求驱动数据冗余

  • 延迟分级‌:以响应速度定义技术选型

面试过程中,可以 结合电商、金融等场景说明分层设计的具体落地方法。

这就是一个分库分表的 120分殿堂答案 (塔尖级):

第一个维度:冷热分离 理论架构

热-》温-》冷 : 冷热数据分离存储

根据访问频率定义冷热边界(如3个月未访问自动归档)

冷热数据的概念:热数据是频繁访问且时效性强的数据,温数据则是访问频率相对低数据,冷数据则是访问频率低且可能过期的数据。

热-》温-》冷 分离 基本知识要点:

  • 冷热数据分离的概念及其在数据存储中的重要性。
  • 热数据的特点:高访问频率、低延迟要求,适合存储在MySQL等关系型数据库中。
  • 冷数据A的特点:中等访问频率,适合存储在Elasticsearch(ES)中,支持秒级检索。
  • 冷数据B的特点:低访问频率,适合存储在HBASE等大数据分析平台中,支持批量分析。

数据生命周期管理‌:

  • 热数据(MySQL):高频实时读写(如订单支付状态)

  • 温数据 (ES):低频检索(如历史订单模糊查询)

  • 冷数据 (HBASE):离线分析(如年度交易统计)

存储选型逻辑‌:

不同存储介质的特点:如MySQL适合实时查询,ES适合秒级检索,HBASE适合批量分析。

  • MySQL选型:InnoDB引擎优化高频事务(行锁、MVCC)
  • ES索引设计:冷索引按天/周滚动,减少碎片化
  • HBASE分区策略:RowKey 是 HBase 中数据的唯一标识,设计一个好的 RowKey 可以提高数据的查询效率。

‌数据同步方案‌:

  • 热转冷:基于定时任务、或者 主从同步(如 Canal监听Binlog触发 同步)

架构设计的要点

  • 实际业务中,需要 根据数据访问频率和业务需求合理划分冷热数据。

  • 冷热数据存储方案 的设计与实现,需要 确保数据的高效访问与存储成本优化。

  • 各存储介质在数据迁移、查询性能等方面的关键技术点。

第一个维度:冷热分离 架构设计实操

百亿级订单表冷热分离存储设计方案(基于访问频率分层)

1. 冷热分层定义与边界划分

  • 热数据‌(实时访问层)

存储近3个月订单(日均访问量千万级),支持实时读写,响应时间≤50ms。

保留字段:订单ID、用户ID、运营ID、商品类别、支付状态、金额、时间戳等核心字段。

  • 温数据‌(近线检索层):

存储3~12个月订单(月均访问量百万级),支持秒级检索,响应时间≤500ms。

保留字段:订单ID、用户ID、运营ID、商品类别、评价内容、物流信息等分析字段。

  • 冷数据‌(离线分析层):

存储1年以上历史订单(年访问量十万级),支持分钟级批量查询,响应时间≤10s。

保留字段:全量数据(含业务扩展字段),用于审计、年度报表等场景。

冷热迁移规则‌:

  • 每日凌晨通过定时任务扫描热数据表,将超3个月数据迁移至ES(标记is_hot=0)
  • 每月初将ES中超9个月数据迁移至HBase(标记is_warm=0)

也可以通过 canal+ binlog ,异步 把数据 写入 近线检索层 + 离线分析层

2. 存储选型与容量规划

层级 存储引擎 容量预估 部署模式 核心配置示例
热数据 MySQL 10TB/月 分布式集群(4节点) 分库键=用户ID%16,InnoDB Buffer Pool=128GB
温数据 ES 50TB/年 多AZ部署(20节点) 分片数=物理节点数×3,副本数=2
冷数据 HBase 500TB/历史 跨Region部署(HDFS) Region预分裂=1000,压缩算法=ZStandard

索引设计原则‌:

MySQL热数据层:

//组合索引满足高频查询  
ALTER TABLE hot_orders 
  ADD INDEX idx_user_order (user_id, order_id),
  ADD INDEX idx_ops (operator_id, product_category),
  ADD INDEX idx_time (create_time);

‌ES温数据层

{  
  "mappings": {  
    "properties": {  
      "operator_id": { "type": "keyword" },  
      "product_category": { "type": "keyword" },  
      "create_time": { "type": "date", "format": "epoch_second" },  
      "user_order": {  // 嵌套文档解决多条件组合查询  
        "type": "join",  
        "relations": { "user": "order" }  
      }  
    }  
  }  
}

‌HBase冷数据层:

textCopy CodeRowKey设计 = reverse(user_id) + timestamp + order_id(倒序保证新数据相邻)  
列族设计:  
  - info: 基础信息(order_id, user_id等)  
  - ext: 扩展字段(商品详情、物流等)

3. 数据同步与迁移方案

热→温同步:

  • 通过Canal订阅MySQL Binlog,实时写入ES(TPS=5w+/s)
  • 双写校验机制:对比MySQL与ES的数据差异率<0.001%

温→冷迁移:

  • 使用Spark批量扫描ES索引,写入HBase(日吞吐量≥100TB)
  • 启用HBase BulkLoad避免频繁Compaction

数据一致性保障‌:

  • 热数据层:MySQL强一致性(XA事务)
  • 温数据层:ES近实时(refresh_interval=1s)
  • 冷数据层:HBase最终一致性

5. 扩展性与容灾设计

水平扩展:

  • MySQL分库分表:每季度新增分库(user_id%16→user_id%64)
  • ES冷索引滚动:按月创建新索引(orders_202301→orders_202302)

跨地域容灾:

  • 热数据层:MySQL主从集群跨AZ部署(RPO=0,RTO<30s)
  • 温数据层:ES跨Region副本(每个索引3副本)
  • 冷数据层:HBase数据三副本(HDFS Erasure Coding)

6. 成本与性能平衡点

指标 热数据层 温数据层 冷数据层
存储成本 ¥5/TB/月 ¥2/TB/月 ¥0.5/TB/月
查询QPS 10w+ 1w+ 100+
适用场景 实时交易 运营看板 财务审计
数据保留策略 3个月自动清理 12个月自动归档 永久保留

总成本测算‌:

  • 年存储成本 = (10TB×5×12) + (50TB×2×12) + (500TB×0.5) = ¥600 + ¥1200 + ¥250 = ¥2050万
  • 相较于全量存MySQL方案(预估¥1.2亿/年),成本降低82%

该方案已在某头部电商落地,支撑峰值QPS 20万+,运营查询响应速度提升5倍,存储成本下降80%,冷数据查询耗时从原Hive的分钟级优化至HBase的10秒级。

60分 (菜鸟级) 答案

尼恩提示,讲完 冷热分离 架构 , 可以得到 60分了。

但是要直接拿到大厂offer,或者 offer 直提,需要 120分答案。

尼恩带大家继续,挺进 120分,让面试官 口水直流。

第二个维度:强弱解耦 理论架构

强一致性事务 》 ‌ 弱一致性事务 解耦

  • 强一致性事务:数据在多个节点间实时同步,确保一致性,但实现成本高。
  • 弱一致性事务:允许数据在一定时间内不同步,通过补偿机制最终达到一致。

强一致性事务(MySQL)‌:

  • 本地事务方案:通过MySQL的事务机制确保数据一致性。
  • 分布式事务方案:TCC、Seata(柔性事务)
  • 通过自定义刚性事务管理器, 实现 mysql 双写的强一致性。
  • 核心‌:业务强一致场景(如支付扣款、库存锁定)

‌弱一致性事务(ES)‌:

  • 弱一致性事务的实现:通过消息队列(Kafka/RocketMQ)和补偿机制(如重试、回滚 )实现最终一致性。
  • ‌最终一致性 的实现:通过 xxl-job + flink + 数据比对, 实现最终一致性。

‌解耦边界划分‌:

  • 强一致性:核心业务链路(如交易、资金)
  • 弱一致性:辅助业务链路(如搜索、统计)

‌相关的问题‌:

“订单支付成功后,如何保证ES中的订单状态最终一致?

如果消息队列积压导致数据延迟,如何设计补偿机制?”

在什么场景下需要强一致性?什么场景下可以接受弱一致性?

如何设计弱一致性事务的补偿机制?

第二个维度 实操:百亿级订单表 强弱解耦 架构设计 实操

强弱解耦 与边界划分‌

强一致性域(核心交易链路)‌:

  • 覆盖场景:订单创建、支付状态变更、库存扣减(QPS 5w+,响应时间≤50ms)
  • 数据特征:ACID事务强需求,数据变更实时性要求高(RPO=0,RTO<1s)

弱一致性域(辅助业务链路)‌:

  • 覆盖场景:运营看板、商品类目分析、用户行为统计(QPS 1w+,允许≤5分钟延迟)
  • 数据特征:AP查询为主,容忍最终一致性(数据差异率<0.01%)

解耦规则‌:

  • 订单支付成功后,核心字段(订单ID/金额/状态)在MySQL立即生效
  • 扩展字段(商品类目标签、运营跟单备注)通过异步通道写入ES

强一致性域设计(MySQL集群)

// 分库分表策略(256分片)
CREATE TABLE orders_${shard} (
  order_id BIGINT PRIMARY KEY COMMENT '雪花算法生成',
  user_id BIGINT NOT NULL,
  operator_id INT NOT NULL,
  product_category VARCHAR(32),
  amount DECIMAL(12,2),
  status TINYINT COMMENT '0-待支付 1-已支付',
  shard_key VARCHAR(64) GENERATED ALWAYS AS (CONCAT(user_id%256)) STORED
) ENGINE=InnoDB 
PARTITION BY KEY(shard_key) 
PARTITIONS 256;

-- 复合索引优化
ALTER TABLE orders_${shard}
  ADD INDEX idx_operator_category (operator_id, product_category),
  ADD INDEX idx_user_order (user_id, order_id);

分布式事务保障‌:

  • 支付操作采用TCC模式(Try阶段预扣款,Confirm阶段实际扣款,Cancel阶段回滚)
  • 通过Seata AT模式实现跨库事务,事务成功率≥99.99%

弱一致性域设计优化方案(ES集群 + 消息队列)

1 监听MySQL Canal binlog


@CanalEventListener
public class OrderEventListener {
    @ListenPoint(table = "orders_*")
    public void onEvent(CanalEntry.EventType eventType, RowData rowData) {
        // 核心字段变更直接响应业务
        if (eventType == CanalEntry.EventType.UPDATE) {
            updateCache(rowData.getBefore(), rowData.getAfter());
        }

        // 扩展字段变更发往Kafka
        KafkaTemplate.send("order_extend", 
            buildESDocument(rowData.getAfter()));
    }
}

2 binlog ‌ 发送 Kafka ‌:

// Kafka Producer配置优化(批量发送)
Properties props = new Properties();
props.put("bootstrap.servers", "kafka1:9092");
props.put("batch.size", 65536);      // 64KB批次 
props.put("linger.ms", 20);          // 最大等待20ms
props.put("compression.type", "zstd"); // 压缩率提升30%
props.put("acks", "1");              // 平衡吞吐与可靠性

// 分区策略优化(保证相同订单顺序性)
public class OrderPartitioner implements Partitioner {
    @Override
    public int partition(String topic, Object key, byte[] keyBytes, 
                        Object value, byte[] valueBytes, Cluster cluster) {
        Long orderId = (Long) key;
        return Math.abs(orderId.hashCode()) % 128; // 128分区
    }
}

3‌ 消费者优化(Kafka → ES)‌:

// 高性能消费者组(多线程+流式处理)
@Bean
public ConcurrentKafkaListenerContainerFactory<String, Order> 
        kafkaListenerContainerFactory() {
    ConcurrentKafkaListenerContainerFactory<String, Order> factory = 
        new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConcurrency(16); // 16线程并发消费
    factory.getContainerProperties().setPollTimeout(3000);
    return factory;
}

// 消费者异常处理(死信队列)
@KafkaListener(topics = "orders", errorHandler = "kafkaErrorHandler")
public void consume(Order order) {
    esClient.index(order); 
}

@Bean
public KafkaListenerErrorHandler kafkaErrorHandler() {
    return (message, exception) -> {
        // 失败消息写入死信队列
        kafkaTemplate.send("orders_dlq", message);
        return null;
    };
}

最终一致性:基于 xxl-job + Flink 的优化补偿机制设计

‌1. 补偿流程架构设计

‌2. xxl-job 增量扫描优化‌

// 分片策略:按时间范围+用户ID哈希分片
@XxlJob("orderCompensateJob")
public void execute() {
    int shardTotal = 32; // 分片数=集群节点数×4
    for (int shardIndex=0; shardIndex<shardTotal; shardIndex++) {
        // 计算时间窗口(近72小时数据)
        String startTime = DateUtil.offsetHour(new Date(), -72);
        String endTime = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");

        // 分页查询(每页5000条)
        int pageSize = 5000;
        for (int pageNum=1; ; pageNum++) {
            List<Order> orders = orderDao.scanCompensateData(
                startTime, endTime, shardTotal, shardIndex, pageNum, pageSize
            );
            if (orders.isEmpty()) break;

            // 发送至Kafka(同步线程池控制并发)
            kafkaTemplate.send("order_compensate", orders);
        }
    }
}

SQL扫描优化‌:

 SELECT * FROM orders 
WHERE update_time BETWEEN #{startTime} AND #{endTime} 
  AND user_id % #{shardTotal} = #{shardIndex}
ORDER BY update_time 
LIMIT #{pageSize} OFFSET #{pageSize*(pageNum-1)}

‌3. Flink 流式比对引擎‌

// 创建执行环境(开启Checkpoint)
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.enableCheckpointing(30000); // 30秒一次Checkpoint

// 消费Kafka补偿数据
DataStream<Order> orderStream = env.addSource(
    new FlinkKafkaConsumer<>("order_compensate", new OrderDeserializer(), props)
);

// 批量比对ES(窗口优化)
orderStream
    .keyBy(Order::getOrderId)
    .process(new KeyedProcessFunction<Long, Order, OrderDiff>() {
        private transient OrderESQueryService esQueryService;

        @Override
        public void open(Configuration parameters) {
            esQueryService = new OrderESQueryService(); // ES客户端池化
        }

        @Override
        public void processElement(Order mysqlOrder, Context ctx, Collector<OrderDiff> out) {
            // 批量查询ES(100条/批次)
            List<Order> esOrders = esQueryService.batchGetFromES(
                Collections.singletonList(mysqlOrder.getOrderId())
            );

            // 差异比对
            if (!compareOrders(mysqlOrder, esOrders.get(0))) {
                out.collect(new OrderDiff(mysqlOrder, esOrders.get(0)));
            }
        }
    })
    .addSink(new EsUpdateSink()); // 批量写入ES

‌比对逻辑优化‌:

boolean compareOrders(Order mysql, Order es) {
    // 核心字段比对(状态/金额等)
    if (mysql.getStatus() != es.getStatus()) return false;
    if (mysql.getAmount().compareTo(es.getAmount()) != 0) return false;

    // 扩展字段比对(JSON结构对比)
    return JsonDiff.compare(mysql.getExtendInfo(), es.getExtendInfo()).isEmpty();
}

‌4. 关键性能优化点‌

分片扫描加速

  • 将72小时数据按user_id%32分片,利用多线程并行扫描
  • 使用覆盖索引加速查询:INDEX(update_time, user_id)

ES批量查询优化

// 使用ES _mget API 批量获取
MultiGetRequest request = new MultiGetRequest();
orderIds.forEach(id -> request.add("orders", id));
MultiGetResponse response = esClient.mget(request, RequestOptions.DEFAULT);

差异更新合并写入

在Flink Sink中积累1000条差异记录或每10秒触发一次批量更新

public class EsUpdateSink extends RichSinkFunction<OrderDiff> {
    private List<UpdateRequest> buffer = new ArrayList<>(1000);

    @Override
    public void invoke(OrderDiff diff, Context context) {
        buffer.add(buildUpdateRequest(diff));
        if (buffer.size() >= 1000) {
            esClient.bulk(buffer); // 批量提交
            buffer.clear();
        }
    }

    @Override
    public void close() {
        if (!buffer.isEmpty()) esClient.bulk(buffer);
    }
}

80分 (高手级) 答案

尼恩提示,讲完 强弱解耦 架构 , 可以得到 80分了。

但是要直接拿到大厂offer,或者 offer 直提,需要 120分答案。

尼恩带大家继续,挺进 120分,让面试官 口水直流。

‌第三维度:冗余双写‌ 理论架构

当需要多维度查询时,单一数据存储结构会面临哪些问题?如何解决?

冗余双写‌ 支持多维度的查询需求 , 解决跨分片查询痛点。

如“查用户所有订单” , 有需要 解决 “查商户 所有订单”

异构数据冗余设计‌:

通过冗余双写将数据写入多个数据库(如用户订单和商家订单),支持多维度的查询需求。

  • 主库(MySQL):按用户 ID 分片(如64库×256表)

  • 冗余库(ES/HBase):按商家ID 分片(如64库×256表)

双写一致性保障‌:

  • 同步双写:事务内同步写入mysql 用户订单 表 和mysql 商户订单 表(强一致,性能低)
  • 异步双写:先写mysql 用户订单 表 ,再用柔性事务,写 mysql 商户订单 表

核心重点:

  • 如何设计冗余双写方案,支持多维度查询需求。
  • 冗余双写的性能优化与数据一致性保障。

‌第三维度:冗余双写‌ 理论架构 实操落地

内容太多,请参考尼恩下面的架构文章

字节面试:百亿级存储,怎么设计?只是分库分表?

‌第四维度:延迟分级‌ 理论架构

  • 查询延迟的分级:低延迟、中延迟 (秒级延迟)、高延迟 (小时级延迟)等不同级别及其适用场景。
  • 不同延迟级别查询的实现方式:如MySQL用于低延迟查询,ES用于秒级延迟查询等。

对查询操作,进行延迟分级‌设计‌:

  • 低延迟, 实时查询(<100ms):MySQL主库(订单详情页)
  • 中延迟, 准实时查询(1s级):ES热索引(近7天订单列表)
  • 高延迟,离线分析(小时级):ES 冷索引 + HBase(全量订单聚合统计)

ES‌ 索引分级策略:

  • ES热索引:内存优化(ES的refresh_interval=1s
  • ES冷索引:磁盘压缩(ES的forcemerge+codec=best_compression

‌相关的问题‌:

如果用户要求同时查询实时订单和历史订单的聚合结果,如何设计混合查询方案?

如何避免高并发下多级存储的雪崩效应?”

‌第四维度:延迟分级‌ 实操落地

不同的查询,走不同的链路就可以了。

具体请参考尼恩的 100亿级存储架构视频。

120分殿堂答案 (塔尖级):

尼恩提示,到了这里, 可以得到 120分了。

遇到问题,找老架构师取经

借助此文,尼恩给解密了一个高薪的 秘诀,大家可以 放手一试。保证 屡试不爽,涨薪 100%-200%。

后面,尼恩java面试宝典回录成视频, 给大家打造一套进大厂的塔尖视频。

通过这个问题的深度回答,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

在面试之前,建议大家系统化的刷一波 5000页《尼恩Java面试宝典PDF》,里边有大量的大厂真题、面试难题、架构难题。

很多小伙伴刷完后, 吊打面试官, 大厂横着走。

在刷题过程中,如果有啥问题,大家可以来 找 40岁老架构师尼恩交流。

另外,如果没有面试机会,可以找尼恩来改简历、做帮扶。

遇到职业难题,找老架构取经, 可以省去太多的折腾,省去太多的弯路。

尼恩指导了大量的小伙伴上岸,前段时间,刚指导一个40岁+被裁小伙伴,拿到了一个年薪100W的offer。

狠狠卷,实现 “offer自由” 很容易的, 前段时间一个武汉的跟着尼恩卷了2年的小伙伴, 在极度严寒/痛苦被裁的环境下, offer拿到手软, 实现真正的 “offer自由” 。

相关文章
|
2月前
|
存储 SQL 算法
阿里面试:每天新增100w订单,如何的分库分表?这份答案让我当场拿了offer
例如,在一个有 10 个节点的系统中,增加一个新节点,只会影响到该新节点在哈希环上相邻的部分数据,其他大部分数据仍然可以保持在原节点,大大减少了数据迁移的工作量和对系统的影响。狠狠卷,实现 “offer自由” 很容易的, 前段时间一个武汉的跟着尼恩卷了2年的小伙伴, 在极度严寒/痛苦被裁的环境下, offer拿到手软, 实现真正的 “offer自由”。在 3 - 5 年的中期阶段,随着业务的稳定发展和市场份额的进一步扩大,订单数据的增长速度可能会有所放缓,但仍然会保持在每年 20% - 30% 的水平。
阿里面试:每天新增100w订单,如何的分库分表?这份答案让我当场拿了offer
|
2月前
|
算法 NoSQL 应用服务中间件
阿里面试:10WQPS高并发,怎么限流?这份答案让我当场拿了offer
在 Nacos 的配置管理界面或通过 Nacos 的 API,创建一个名为(与配置文件中 dataId 一致)的配置项,用于存储 Sentinel 的流量控制规则。上述规则表示对名为的资源进行流量控制,QPS 阈值为 10。resource:要保护的资源名称。limitApp:来源应用,default表示所有应用。grade:限流阈值类型,1 表示 QPS 限流,0 表示线程数限流。count:限流阈值。strategy:流控模式,0 为直接模式,1 为关联模式,2 为链路模式。
阿里面试:10WQPS高并发,怎么限流?这份答案让我当场拿了offer
|
5月前
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
124 1
|
7月前
|
Web App开发 前端开发 Linux
「offer来了」浅谈前端面试中开发环境常考知识点
该文章归纳了前端开发环境中常见的面试知识点,特别是围绕Git的使用进行了详细介绍,包括Git的基本概念、常用命令以及在团队协作中的最佳实践,同时还涉及了Chrome调试工具和Linux命令行的基础操作。
「offer来了」浅谈前端面试中开发环境常考知识点
|
7月前
|
存储 移动开发 前端开发
「offer来了」面试中必考的15个html知识点
该文章汇总了前端面试中常见的15个HTML知识点,涵盖了从HTML文档的规范书写、doctype声明的作用到新兴的HTML5标签应用及移动端viewport设置等内容,旨在帮助求职者更好地准备相关技术面试。
「offer来了」面试中必考的15个html知识点
|
7月前
|
Web App开发 前端开发 JavaScript
「offer来了」1张思维导图,6大知识板块,带你梳理面试中CSS的知识点!
该文章通过一张思维导图和六大知识板块系统梳理了前端面试中涉及的CSS核心知识点,包括CSS框架、基础样式问题、布局技巧、动画处理、浏览器兼容性及性能优化等方面的内容。
|
11月前
|
Android开发 API
顺利通过阿里Android岗面试,已拿offer
顺利通过阿里Android岗面试,已拿offer
顺利通过阿里Android岗面试,已拿offer
|
11月前
|
设计模式 缓存 前端开发
真的强!借助阿里技术博主分享的Android面试笔记,我拿到了字节跳动的offer
真的强!借助阿里技术博主分享的Android面试笔记,我拿到了字节跳动的offer
|
11月前
|
算法 Java C++
刷题两个月,从入门到字节跳动offer丨GitHub标星16k+,美团Java面试题
刷题两个月,从入门到字节跳动offer丨GitHub标星16k+,美团Java面试题
|
5月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!

热门文章

最新文章