zoukankan      html  css  js  c++  java
  • 浮点数表示 & 缓存 & 布隆过滤器

    浮点数表示 & 缓存 & 布隆过滤器

    • 1.计算机是如何表示小数
    • 2.缓存
    • 3.布隆过滤器

    1.浮点数的表示

    引子: 我们先看一个错误示例

    public static void main(String[] args) {
    		System.out.println(1f == 0.999999f);          // false
        System.out.println(1f == 0.9999999f);         // false
        System.out.println(1f == 0.99999999f);        // true
        System.out.println(1f == 0.999999999999f);    // true
    }
    

    注意: 不能使用 "==" 对浮点值进行判断

    浮点数之间的等值判断,基本数据类型不能使用 "==" ,包装数据类型不能使用 equals来判断  --- 阿里巴巴Java开发手册[强制]
    

    为什么浮点数不能使用 "==" 判断 ?

    计算机是如何表示小数的?

    十进制小数

    [D = sum^{m}_{i=-n} d_{i} * 10^{i} ]

    二进制小数

    [B = sum_{i= -n}^{m} b_{i}*2^{i} ]

    IEEE-745浮点标准

    [V = (-1)^s * M *2^E ]

    • s 符号位
    • M 阶码部分
    • E 尾数部分

    符号s: 0正,1负

    阶码E: float 8bit(-128,127) double 11bit(-1023,1024)

    尾数M:float 23bit double 52bit

    [V = x * 2^y ]

    根据exp的值,被编码的值可以分为三种

    • 规格化的值
    • 非规格化的值
    • 特殊值

    1.规格化的值

    [E = e - Bias ]

    [M = 1+ f ]

    • e - exp表达式的值
    • Bias

    [Bias = 2^{k-1} -1 ; (127,1023) ]

    • M - 调整阶码的值

    [1101.111 = 1.101111 * 2^{3} ]

    案例example

    [13.875_{10} = 1101.111_{2} = 1.101111_{2} * 2^{3} ]

    [M = 1 +f ]

    [f = 1011111 ]

    [e = E + Bias = 3 + 127 = 130_{10} = 10000010_{2} ]

    13.875
    Sign Exponent Mantissa
    0x415E0000 = 01000001 01011110 00000000 00000000 0 10000010 10111100000000000000000

    浮点数在线转换

    2.非规格化的值

    [E = 1- Bias ]

    [M = f ]

    3.特殊值

    a.当exp全部为1,小数域全为0,表示无穷

    b.当exp全部为1,小数域frac不等于0,表示NaN(not a number)

    2.缓存

    应用缓存 ->性能优化案例:

    • 操作系统
    • 数据库
    • 分布式缓存
    • 本地缓存

    缓存目的: 弥补cpu高算力和IO读写慢之间的鸿沟

    缓存

    缓存问题

    3.布隆过滤器

    如何判断一个元素是否已经存在?

    1.set集合

    2.数据+hash , index = hash(xx) % table.length

    3.Bloom Filter

    布隆过滤器:

    • 减少hash冲突,优化hash函数(多个hash实现)

    • 增加数组长度

      假设用100w的数据量

      • 使用int数组

      [1*10^{6} * 4 (Byte) = 4*10^{6}/1024 = 4000k ]

      • 使用位数组

      [1*10^{6} / 8 = 125000(byte) = 127k ]

    布隆过滤器的判断方法

    • 布隆过滤器判定某个元素存在,其实有可能存在(hash冲突)
    • 布隆过滤器判定某个元素不存在,则一定不存在

    布隆过滤器的使用场景

    • 判断数据在海量数据中是否存在,防止缓存穿透
    • 判定某个URL是否已经处理过

    布隆过滤器的实现

    package src.bloomFilter;
    import java.util.BitSet;
    
    /**
     * @Author deng shuo
     * @Date 6/12/21 10:07
     * @Version 1.0
     */
    public class MyBloomFilter {
        
        private static final int DEFAULT_SIZE = 2 << 24;
        
        private static int[] SEEDS = new int[]{3,13,46};
        
        private static BitSet bits = new BitSet(DEFAULT_SIZE);
        
        private SimpleHash[] func = new SimpleHash[SEEDS.length];
        
        public MyBloomFilter(){
            for(int i = 0;i< SEEDS.length;i++){
                func[i] = new SimpleHash(DEFAULT_SIZE,SEEDS[i]);
            }
        }
        
        public void add(Object value){
            for(SimpleHash f: func){
                bits.set(f.hash(value),true);
            }
        }
        
        public boolean contains(Object value){
            boolean res = true;
            for(SimpleHash f:func){
                res = bits.get(f.hash(value));
                if(!res){
                    return false;
                }
            }
            return true;
        }
        
        public static class SimpleHash{
            private int cap;
            private int seed;
            
            public SimpleHash(int cap ,int seed){
                this.cap = cap;
                this.seed = seed;
            }
            public int hash(Object value){
                int h;
                return (value == null) ? 0:
                        Math.abs(seed*(cap -1) & (h=value.hashCode())^(h>>>16));
            }
        }
        
    }
    
    

    Guava工具库实现布隆过滤器

    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>27.0.1-jre</version>
    </dependency>
    
    // 创建布隆过滤器对象,最多元素数量为10000,期望误报概率为0.01
    BloomFilter<Integer> filter = BloomFilter.create(
            Funnels.integerFunnel(), 10000, 0.01);
    
    不要用狭隘的眼光看待不了解的事物,自己没有涉及到的领域不要急于否定. 每天学习一点,努力过好平凡的生活.
  • 相关阅读:
    采样错误
    MathJax
    jupyter
    pip
    str操作
    Content-Type
    json转csv
    【tornado】静态文件
    dict 字典
    基于插件技术的GIS应用框架(C# + ArcEngine9.3)(一)
  • 原文地址:https://www.cnblogs.com/GeekDanny/p/14877793.html
Copyright © 2011-2022 走看看