前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >业务开发中你用到了哪些算法?

业务开发中你用到了哪些算法?

作者头像
一猿小讲
发布2019-12-09 14:35:55
5340
发布2019-12-09 14:35:55
举报
文章被收录于专栏:一猿小讲一猿小讲

【这是一猿小讲的第 73 篇原创分享】

S哥:今天去面试啦,简历上写了一句“熟练运用算法于应用中”,面试官问我时,却不知道说啥(很尴尬)...... ME:可以说说 hash 算法,先说说分库分表;然后一致性 hash;然后升华......

年底了,确实有很多默默看机会的盆友,开始躁动了起来。身边很多选手也不例外,身边的 S 哥为了彰显自己牛掰,简历上斗胆撂了一句“熟练运用算法于应用中”,但是当面试官问起时,S 哥却被问的一愣一愣哒。

鉴于此,不妨分享一下我的回答思路,看能否帮你争取点面试分。

先说一个离我们比较近的应用场景。估计多数人还没有经历过分库分表,但是个人感觉,截止到目前稍微有点量级的应用,数据库可能没有拆分,但是订单表应该也被拆分的稀碎啦,这么说你可能不理解,不妨举个栗子。

起初,原有的一张 T_ORDER 足矣满足业务需求,但是随着业务推广,订单表的数据日益增多,数据查询势必会越来越慢,性能是个问题。好的解决方案势必是分开,例如分成 T_ORDER_0、T_ORDER_1、T_ORDER_2 三张滚动表,但是到底该怎么实现这么个策略呢?

码代码的不写点代码,确实不是那么回事儿!

代码语言:javascript
复制
@Test
public void splitTable() throws ParseException {
    //1. 取得当前数据库的时间,一定要用数据库的时间,因为服务器的时间可能会不同。
    //   此处为了示意,临时采用当前系统的时间
    Timestamp current = new Timestamp(System.currentTimeMillis());

    //2. 找一个你比较相中的时间点作为计算参考,例如 2009-7-1
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date date = sdf.parse("2009-7-1");

    //3. 计算当前时间与上面的参考时间相差的天数
    long t1 = current.getTime() - date.getTime();
    long t2 = 1000 * 60 * 60 * 24;
    int days = (int) (t1 / t2);

    //4. 相差的天数除 3 的余数来确定使用哪张订单表
    int lastname = days % 3;
    String tableName = "T_ORDER_" + lastname;

    System.out.println(tableName);
}

上面的代码来自于实际应用,可能代码不雅观,但是线上跑的却很好,所以也无心修理它。但是无论怎么跑,结果总会是 T_ORDER_0、T_ORDER_1、T_ORDER_2 来回切换。

好了,知道了如何分表了,但是如果数据量依旧很大,是不是应该考虑分库啦,不多说,直接摘实际应用中一个较全的代码进行示意。

代码语言:javascript
复制
@Test
public void splitDbTable() throws Exception {
    // 分成 6 个库、共分成 1200 张表
    long dbNum = 6;
    long tableNum = 1200;

    //1. 按照某业务字段为拆分依据,例如按照身份证号进行拆分
    String splitField = "411424201802208888";
    //2. 对选择的业务字段的值取 crc32(字段数值化)
    java.util.zip.CRC32 crc32 = new java.util.zip.CRC32();
    crc32.update(splitField.getBytes("UTF-8"));
    long x = java.lang.Math.abs(crc32.getValue());

    //3. 计算数据库的下标
    long n = x % dbNum;
    String dbPos = String.format("%02d", n);
    System.out.println("数据库的下标:" + dbPos);

    //4. 计算数据库下表对应的下标
    long m = x % tableNum;
    String tablePos = String.format("%03d", m);
    System.out.println("表的下标:" + tablePos);
}

针对上面代码,咱们稍微抽象一点的去说一下(这块需要顿悟,尤其是数学不太好,脑子空间不够的同学,不妨拿个铅笔,算一算)。

抽象正式开始啦,若有 M 个数据库主节点,数据表总计拆分成 N 张子表,拆表字段数值化转换为 X,则数据库实例的序号为 X % M ;数据表的序号为 X % N。

例如:当主节点个数 M=6,总计拆表数 N=1200 时(单库内子表个数为 200),则数据库实例的序号 X % 6;数据表的序号为 X % 1200。

于是:序号为 0 的数据库中,会有序号为 0,6,12,18… 的数据表;序号为 1 的数据库中,会有序号为 1,7,13,19… 的数据表;以此类推。

拆表字段数值化机制:取拆表依据字段,对其取 crc32,之后取绝对值,即为上述“分库分表公式”中的 X。

好了,到这距离咱们研发最近的 hash 算法就聊明白了,估计到这估计面试官也被你搞懵啦!

但是面试中经常会谈及一致性 hash,到底要聊的是个啥呢?Memcached 里面用到了吗?Nginx 里面用到了吗?MapReduce 里面用到了吗?数据倾斜又是怎么回事呢?

未完待续,且听下回分解。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一猿小讲 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档