This class provides protected overridable beforeExecute(Thread, Runnable) and afterExecute(Runnable, Throwable) methods that are called before and after execution of each task. These can be used to manipulate the execution environment; for example, reinitializing ThreadLocals, gathering statistics, or adding log entries. Additionally, method terminated() can be overridden to perform any special processing that needs to be done once the Executor has fully terminated.
/* * Proceed in 3 steps: * * 1. If fewer than corePoolSize threads are running, try to * start a new thread with the given command as its first * task. The call to addWorker atomically checks runState and * workerCount, and so prevents false alarms that would add * threads when it shouldn't, by returning false. * * 2. If a task can be successfully queued, then we still need * to double-check whether we should have added a thread * (because existing ones died since last checking) or that * the pool shut down since entry into this method. So we * recheck state and if necessary roll back the enqueuing if * stopped, or start a new thread if there are none. * * 3. If we cannot queue task, then we try to add a new * thread. If it fails, we know we are shut down or saturated * and so reject the task. */
雪花算法(Snowflake)是 Twitter 提出来的一个算法,其目的是生成一个 64 bit 的二进制数:
转换为十进制和十六进制分别如下图。其中十进制的最大长度为 19 位:
该二进制数分解如下:
42 bit:用来记录时间戳,表示自 1970-01-01T00:00:00Z 之后经过的毫秒数(millisecond),其中 1 bit 是符号位。由于精确到毫秒(millisecond),相比有符号 32 bit 所存储的精度为秒(second)的时间戳需要多 10 bit 来记录毫秒数(0-999)。42 bit 可以记录 69 年,如果设置好起始时间例如 2018 年,那么可以用到 2087 年。42 bit 时间戳范围如下:
publicstaticvoidlog(long id) { longtimestamp= id >> TIMESTAMP_SHIFT; longdataCenterNo= id >> DATA_CENTER_NO_SHIFT & MAX_DATA_CENTER_NO; longworkerNo= id >> WORKER_NO_SHIFT & MAX_WORKER_NO; longseqNo= id >> SEQ_NO_SHIFT & MAX_SEQ_NO; longext= id & MAX_EXT;
log.info("Binary is {}, id is {}", Long.toBinaryString(id), id); log.info("Binary is {}, time is {}", Long.toBinaryString(timestamp), getLocalDateTime(timestamp)); log.info("Binary is {}, dataCenterNo is {}", Long.toBinaryString(dataCenterNo), dataCenterNo); log.info("Binary is {}, workerNo is {}", Long.toBinaryString(workerNo), workerNo); log.info("Binary is {}, seqNo is {}", Long.toBinaryString(seqNo), seqNo); log.info("Binary is {}, ext is {}", Long.toBinaryString(ext), ext); }
Binary is 110000011011010011001111001101001100000111000011000000000100000, id is 6979004485312020512 Binary is 11000001101101001100111100110100110000011, time is 2022-09-23T17:12:12.931 Binary is 10, dataCenterNo is 2 Binary is 11, workerNo is 3 Binary is 100, seqNo is 4 Binary is 0, ext is 0
A foreign key relationship involves a parent table that holds the initial column values, and a child table with column values that reference the parent column values. A foreign key constraint is defined on the child table.
It applies a hash function to the username and password before sending them over the network. In contrast, basic access authentication uses the easily reversible Base64 encoding instead of hashing, making it non-secure unless used in conjunction with TLS.
In cryptography, a message authentication code (MAC), sometimes known as a tag, is a short piece of information used for authenticating a message. In other words, to confirm that the message came from the stated sender (its authenticity) and has not been changed. The MAC value protects a message’s data integrity, as well as its authenticity, by allowing verifiers (who also possess the secret key) to detect any changes to the message content.
If any change is made to the data being sent, the resulting HMAC will be completely different from the original. Additionally, since the key is known only to the sender and the receiver, no valid HMAC can be regenerated by anyone else.
All you need to do is take the HTTP request body and apply the SHA-256 hash function to it, using the secret key as the hash key. You then compare the resulting HMAC to the one contained in the Signature header:
If the HMACs are identical, then the data corresponds to what sender sent.
If they are different, this indicates that the data has been intercepted and altered in some way.
explain select id from t_order where create_time between'2019-10-17'and'2019-10-25' limit 1000000, 10;
+----+-------------+---------+-------+-----------------+-----------------+---------+------+---------+--------------------------+ | id | select_type |table| type | possible_keys | key | key_len |ref|rows| Extra | +----+-------------+---------+-------+-----------------+-----------------+---------+------+---------+--------------------------+ |1| SIMPLE | t_order |range| idx_create_time | idx_create_time |5|NULL|3775048|Usingwhere; Using index | +----+-------------+---------+-------+-----------------+-----------------+---------+------+---------+--------------------------+
上述查询字段改为 id 后,执行计划中新增: Extra=Using index,表示走覆盖索引,无需回表,查询速度快了 N 倍。
延迟关联优化
延迟关联优化涉及到了 SQL 优化的两个重要概念:覆盖索引和回表。
通过覆盖索引在辅助索引上完成所有扫描、过滤、排序(利用索引有序)和分页;
最后通过主键回表查询,最大限度减少回表查询的 I/O 次数。
SQL 改造如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
explain select*from t_order t innerjoin ( select id from t_order where create_time between'2019-10-17'and'2019-10-25' limit 1000000, 10 ) e on t.id = e.id;
+----+-------------+---------------+--------+-----------------+-----------------+---------+------+---------+--------------------------+ | id | select_type |table| type | possible_keys | key | key_len |ref|rows| Extra | +----+-------------+---------------+--------+-----------------+-----------------+---------+------+---------+--------------------------+ |1|PRIMARY|<derived2>|ALL|NULL|NULL|NULL|NULL|1000010|NULL| |1|PRIMARY| t | eq_ref |PRIMARY|PRIMARY|8| e.id |1|NULL| |2| DERIVED | t_order |range| idx_create_time | idx_create_time |5|NULL|3775048|Usingwhere; Using index | +----+-------------+---------------+--------+-----------------+-----------------+---------+------+---------+--------------------------+