Tencent Two Sides: hay 4 mil millones de números QQ y la memoria está limitada a 1 G. ¿Cómo deduplicar? ¡Me quedé estupefacto con la pregunta!

4 mil millones de números QQ, limitados a memoria 1G, ¿cómo deduplicar?

4 mil millones de entradas sin firmar, si se almacenan directamente en la memoria, necesitan:

4*4000000000 /1024/1024/1024 = 14.9G, teniendo en cuenta que hay algunas palabras repetidas, el espacio de 1G básicamente no es suficiente.

Para lograr esta función, puede utilizar un mapa de bits.

Si usa un mapa de bits, un número solo necesita ocupar 1 bit, por lo que 4 mil millones de números son:

4000000000 * 1 /8 /1024/1024 = 476M

Comparado con el 14.9G anterior, ahorra mucho espacio.

Por ejemplo, si quiero poner mi número QQ "907607222" en el mapa de bits, necesito encontrar la posición de 907607222 y luego establecerla en 1.

De esta manera, después de poner 4 mil millones de números en el mapa de bits, todas las posiciones de 1 indican existencia y las que no son de 1 indican inexistencia. El mismo número QQ solo necesita establecerse en 1 una vez. Entonces, al final, todos son El número de 1 se puede atravesar.

¿Qué son los mapas de bits? ¿Cuál es el uso?

Bitmap (BitMap), la idea básica es utilizar un bit para marcar un elemento. Bit es la unidad más pequeña en una computadora, es decir, lo que solemos llamar 0 y 1 en una computadora. Esto se representa por un bit.

El llamado mapa de bits es en realidad una matriz de bits, es decir, cada posición es un bit, y el valor que contiene puede ser 0 o 1

Al igual que el mapa de bits anterior, se puede utilizar para representar 1, 4, 6:

Si no usamos un mapa de bits, si queremos registrar los tres enteros de 1, 4 y 6, necesitamos usar tres ints sin signo. Se sabe que cada int sin signo ocupa 4 bytes, por lo que es un byte, una 3*4 = 12palabra Una sección tiene 8 bits, por lo que es 12*8 = 96un bit.

Por lo tanto, el mayor beneficio de los mapas de bits es ahorrar espacio.

Los mapas de bits tienen muchos usos, especialmente en escenarios como la deduplicación y la clasificación. El famoso filtro Bloom se implementa en función de los mapas de bits.

Pero el mapa de bits también tiene ciertas limitaciones, es decir, solo puede representar el 0 y el 1, y no puede almacenar otros números. Por lo tanto, solo es adecuado para este tipo de escena que puede expresar verdadero o falso.

Recomiende un proyecto práctico Spring Boot de código abierto y gratuito:

https://github.com/javastacks/spring-boot-best-practice

¿Qué es un filtro Bloom y cuál es su principio de implementación?

Un filtro Bloom es una estructura de datos utilizada para recuperar rápidamente si es probable que exista un elemento en un conjunto (matriz de bits).

Su principio básico es usar múltiples funciones hash para mapear un elemento en múltiples bits y luego establecer estos bits en 1. Al consultar un elemento, si todos estos bits están establecidos en 1, se considera probable que el elemento exista en la colección; de lo contrario, definitivamente no existe.

Por lo tanto, el filtro Bloom puede determinar con precisión si un elemento no debe existir, pero debido a la existencia de colisiones hash, no puede determinar si un elemento debe existir. Sólo puede juzgarse que puede existir.

Por lo tanto, existe la posibilidad de un error de juicio en el filtro Bloom, es decir, cuando un elemento Hero inexistente pasa por hash1, hash2 y hash3, entra en conflicto con los resultados hash de otros valores. Entonces se juzgará erróneamente que existe, pero en realidad no existe.

Para reducir la probabilidad de este error de juicio, el método principal es reducir la probabilidad de colisión de hash e introducir más algoritmos de hash.

El siguiente es el proceso de trabajo del filtro Bloom:

1. Inicializar el filtro Bloom

Al inicializar el filtro Bloom, debe especificar el tamaño del conjunto y la tasa de falsos positivos. El filtro Bloom contiene una matriz de bits y varias funciones hash, y cada función hash genera un valor de índice.

2. Agrega elementos al filtro Bloom

Para agregar un elemento al filtro Bloom, primero es necesario pasar el elemento a través de múltiples funciones hash para generar múltiples valores de índice y luego establecer los bits correspondientes a estos valores de índice en 1. Si estos valores de índice ya se han establecido en 1, no es necesario volver a establecerlos.

3. Si el elemento de consulta existe en el filtro Bloom

Para consultar si un elemento existe en el filtro Bloom, es necesario pasar el elemento a través de múltiples funciones hash para generar múltiples valores de índice y determinar si los bits correspondientes a estos valores de índice están todos establecidos en 1. Si todos estos bits están establecidos en 1, se considera probable que el elemento esté presente en el conjunto; de lo contrario, definitivamente no lo está.

La principal ventaja del filtro Bloom es que puede determinar rápidamente si un elemento pertenece a un determinado conjunto y puede lograr una alta eficiencia en el espacio y el tiempo. Sin embargo, también tiene algunas desventajas, tales como:

  1. El filtro Bloom tiene una cierta tasa de error al juzgar si existe un elemento. ,
  2. Los filtros Bloom eliminan elementos con mayor dificultad, porque eliminar un elemento requiere establecer sus bits correspondientes en 0, pero estos bits pueden ser compartidos por otros elementos.

Escenario de aplicación

El filtro Bloom es muy utilizado por su alta eficiencia, los escenarios típicos son los siguientes:

1. Rastreador web: los programas rastreadores pueden usar filtros Bloom para filtrar páginas web que ya se han rastreado para evitar el rastreo repetido y el desperdicio de recursos.

2. Sistema de caché: el sistema de caché puede usar filtros Bloom para juzgar si una consulta puede existir en el caché, lo que reduce la cantidad de cachés de consultas y mejora la eficiencia de las consultas. Los filtros Bloom también se utilizan a menudo para resolver el problema de la penetración de caché.

3. Sistema distribuido: en un sistema distribuido, se puede usar un filtro Bloom para determinar si existe un elemento en la memoria caché distribuida, evitando consultas en todos los nodos y reduciendo la carga de la red.

4. Filtrado de correo no deseado: el filtro Bloom se puede usar para juzgar si una dirección de correo electrónico está en la lista de correo no deseado, a fin de filtrar el correo no deseado.

5. Filtrado de listas negras: el filtro Bloom se puede usar para determinar si una dirección IP o un número de teléfono móvil está en la lista negra, evitando así solicitudes maliciosas.

cómo utilizar

Los filtros Bloom se pueden implementar utilizando bibliotecas de terceros en Java. Las más comunes incluyen la biblioteca Google Guava, la biblioteca Apache Commons y Redis.

Como la guayaba:

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
public class BloomFilterExample {
    public static void main(String[] args) {
        // 创建布隆过滤器,预计插入100个元素,误判率为0.01
        BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(), 100, 0.01);
        // 插入元素
        bloomFilter.put("Lynn");
        bloomFilter.put("666");
        bloomFilter.put("八股文");
        // 判断元素是否存在
        System.out.println(bloomFilter.mightContain("Lynn")); // true
        System.out.println(bloomFilter.mightContain("张三"));  // false
    }
}

Apache Commons:

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.collections4.BloomFilter;
import org.apache.commons.collections4.functors.HashFunctionIdentity;
public class BloomFilterExample {
    public static void main(String[] args) {
        // 创建布隆过滤器,预计插入100个元素,误判率为0.01
        BloomFilter<String> bloomFilter = new BloomFilter<>(HashFunctionIdentity.hashFunction(StringUtils::hashCode), 100, 0.01);
        // 插入元素
        bloomFilter.put("Lynn");
        bloomFilter.put("666");
        bloomFilter.put("八股文");
        // 判断元素是否存在
        System.out.println(bloomFilter.mightContain("Lynn")); // true
        System.out.println(bloomFilter.mightContain("张三"));  // false
    }
}

Redis se puede usar a través del módulo Bloom y Redisson se puede usar para:

Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
RBloomFilter<String> bloomFilter = redisson.getBloomFilter("myfilter");
bloomFilter.tryInit(100, 0.01);
bloomFilter.add("Lynn");
bloomFilter.add("666");
bloomFilter.add("八股文");
System.out.println(bloomFilter.contains("Lynn"));
System.out.println(bloomFilter.contains("张三"));
redisson.shutdown();

Primero cree un objeto RedissonClient y luego obtenga un objeto RBloomFilter a través de este objeto, use el método tryInit para inicializar el filtro Bloom, especifique la cantidad máxima de elementos que se pueden agregar como 100 y la tasa de falsos positivos es 0.01.

Luego, use el método add para agregar los elementos "狗小HA", "666" y "八边文" al filtro Bloom, y use el método contains para verificar si el elemento existe en el filtro Bloom.

O los Jedi también pueden:

Jedis jedis = new Jedis("localhost");
jedis.bfCreate("myfilter", 100, 0.01);
jedis.bfAdd("myfilter", "Lynn");
jedis.bfAdd("myfilter", "666");
jedis.bfAdd("myfilter", "八股文");
System.out.println(jedis.bfExists("myfilter", "Lynn"));
System.out.println(jedis.bfExists("myfilter", "张三"));
jedis.close();

Declaración de derechos de autor: este artículo es un artículo original del blogger de CSDN "code.song", siguiendo el acuerdo de derechos de autor CC 4.0 BY-SA, adjunte el enlace de la fuente original y esta declaración para su reimpresión. Enlace original: https://blog.csdn.net/songmulin/article/details/130814507

Recomendación de artículo reciente:

1. Más de 1000 preguntas y respuestas de entrevistas en Java (última versión de 2022)

2. ¡Brillante! Las corrutinas de Java están llegando. . .

3. Tutorial de Spring Boot 2.x, ¡demasiado completo!

4. No llenes la pantalla de explosiones y explosiones, prueba el modo decorador, ¡esta es la forma elegante! !

5. La última versión del "Manual de desarrollo de Java (edición Songshan)", ¡descárguelo rápidamente!

¡Siéntete bien, no olvides darle me gusta + adelante!

Supongo que te gusta

Origin blog.csdn.net/youanyyou/article/details/130954898
Recomendado
Clasificación