是什么大仙风把你给刮来了🍃?
快来看看有没有你感兴趣的东西,我亲爱的朋友😉。
Kafka Kafdrop services: kafdrop: image: obsidiandynamics/kafdrop container_name: kafdrop ports: - "9000:9000" environment: KAFKA_BROKERCONNECT: "localhost:9092" SERVER_SERVLET_CONTEXTPATH: "/" restart: unless-stopped KRaft 模式 services: kafka: image: apache/kafka:3.9.0 container_name: kafka hostname: kafka ports: - "9092:9092" environment: KAFKA_NODE_ID: 1 KAFKA_PROCESS_ROLES: broker,controller KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093 # 注意:这里不要换行,不要逗号 KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093 # 外部访问地址 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092 KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1 CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk volumes: - ./data:/var/lib/kafka/data restart: unless-stopped
在 Java 的世界里,“分代年龄”(Age) 是专门为 JVM 垃圾回收(GC)设计的一个计数器。 简单来说,它记录了一个 Java 对象在垃圾回收中活过了多少轮。就像打游戏刷副本一样,对象每在垃圾回收的“清洗”中幸存下来一次,它的分代年龄就会 +1。 1. 为什么需要“分代年龄”? 这源于 Java 垃圾回收领域著名的 弱分代假说(Weak Generational Hypothesis): 绝大多数的 Java 对象都是“朝生夕死”的。 比如你在一个方法里 new 了一个局部变量,方法结束了,这个对象就没用了。但也有极少数对象(如 Spring 的 Bean、数据库连接池)会一直存活。 为了高效管理内存,JVM 把堆内存分成了两大区域: 新生代(Young Generation): 存放刚出生、寿命短的对象。 老年代(Old Generation): 存放寿命长、常驻内存的对象。 “分代年龄”就是对象从“新生代”晋升到“老年代”的资格证和进度条。 2. 它的工作流程是怎样的? 我们可以把新生代想象成一个“新手村”,老年代想象成“满级主城”: 出生(0岁): 绝大多数新对象在新生代的 Eden(伊甸园)区 出生。 第一次渡劫(1岁): 发生了一次 Minor GC(新生代垃圾回收)。如果这个对象没被回收,它会幸存下来,被移动到 Survivor(幸存者)区,同时它的分代年龄变成 1 岁。 继续熬资历(每活过一轮 +1岁): 以后每发生一次 Minor GC,只要它还在幸存者区折腾且没死掉,它的年龄就会加 1 岁。 晋升老年代: 当它的年龄达到一定阈值(默认是 15 岁,由 JVM 参数 -XX:MaxTenuringThreshold 决定)时,JVM 就会认为:“这小伙子挺能活,应该是个核心常驻对象。” 于是把它晋升(Promote)到老年代。 3. 它存在对象的什么地方? 正如我们在讨论“锁”时提到的,分代年龄存在于每个 Java 对象的 对象头(Object Header)的 Mark Word 里面。 ...
1. 为什么当初要这样设计?(设计初衷) Java 诞生于 20 世纪 90 年代中期,当时多线程编程(并发)正在兴起。Java 的设计者高斯林(James Gosling)希望 Java 成为一门简单易用的多线程语言。 简化并发编程 如果对象没有内置锁,你每次想给一段代码加锁,都必须显式地创建一个 Lock 对象: // 如果没有内置锁,你得这么写: Lock myLock = new ReentrantLock(); void doSomething() { myLock.lock(); try { // 业务逻辑 } finally { myLock.unlock(); } } 而 Java 设计者引入了 synchronized 关键字,直接让对象充当锁,把复杂的同步简化成了: // 极简的同步写法 synchronized(this) { // 业务逻辑 } “万物皆对象,万物皆可为锁”的设计,让开发者不需要管理一堆乱七八糟的锁对象,只要拿到目标对象,就能直接进行同步控制。 2. 这样不浪费内存吗?JVM 是怎么“偷懒”的? 你担心的内存浪费,JVM 工程师早就想到了。他们绝对不会傻到给每个刚 new 出来的对象都分配一个沉重的操作系统级别的锁(Monitor)。 JVM 解决这个问题的核心思路是:按需分配,动态升级。 秘密武器:对象头(Object Header) 在 Java 中,每个对象的内存结构里都有一个叫 Mark Word(标记字) 的区域(在 64 位虚拟机上占 8 个字节 / 64 位)。 ...
在 Java 后端开发面试或源码阅读中,HashMap 永远是避不开的核心。很多人能熟练地背出它的扩容阈值、红黑树化条件,但当深入到源码底层,看到诸如 e.hash & (newCap - 1) 和 e.hash & oldCap 这样的位运算时,往往会陷入沉思。 一、 起源:为什么数组长度必须是 2 的次幂? 在散列表中,为了让数据均匀分布,最直观的想法是对哈希值进行取模(求余数): $$\text{索引位置} = \text{hash} \pmod{\text{Capacity}}$$然而,在 CPU 的底层底层执行中,除法和取模(%)是非常昂贵的算术操作(可能需要几十个时钟周期)。为了追求极致的性能,底层的数论定理为我们提供了一个完美的替代方案: 数学定理:当容量 $C$ 是 $2$ 的次幂($2^n$)时,对于任意整数 $H$,满足: $$H \pmod C \equiv H \ \& \ (C - 1)$$ 位运算(&)在 CPU 中只需要 1 个时钟周期!为了享受到这个性能红利,HashMap 在源码中将容量死死限制为 2 的次幂: // 默认初始容量 16 (2的4次方) static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; 裁剪器的魔术:hash & (newCap - 1) 以容量 16 为例,16 - 1 = 15(二进制:0000 1111)。任何 Hash 值与 15 进行 & 运算,高位都会被无情“抹零”,只有最后 4 位被保留下来: ...
先撕掉一个谎言 你被灌输过一个观念——资源是稀缺的,所以竞争是残酷的,所以你穷是正常的。 这句话每一个字都是错的。 真正的稀缺,几乎从来不是物质的稀缺,而是认知的稀缺。石油曾经是让农田绝收的黑色毒水,稀土曾经是矿渣里没人要的废石,页岩气曾经被写进教科书当作"永远无法开采"的典型。它们不是突然变多了——它们一直在那里,只是人类的技术终于配得上它们了。 所以请记住这个地基,因为后面所有的推理都建立在它之上: 地球的资源上限是未知的,人类的需求是无限的。真正把你困住的,从来不是这个世界没有位置,而是你不知道位置在哪。 明白了这一点,我们才能谈真正的问题——不是资源不够,而是人太懒,并且懒得如此整齐划一。 一、“懒"是人性的底层代码,但懒有段位之分 先说清楚:我说的"懒”,不是道德批判。 懒是人性的默认设置——用最小的付出,换取自己想要的生活。 这没有错,它甚至是效率的本能。真正决定你命运的,不是你懒不懒(你一定懒),而是你懒在哪个段位上。 段位不同,议价能力天差地别。有人懒得一贫如洗,有人懒得财富自由。下面这五层,就是从地狱到天堂的完整阶梯。你现在站在第几层,决定了你现在过什么日子。 flowchart TD A["LV1 懒到活不下去饥饿倒逼求生——不稳定,会被自动弹走"] --> B["LV2 懒到刚好活着被随意替换的螺丝钉——90%的人被困死在这里"] B --> C["LV3 拒绝被剥削看清了机制,愤怒觉醒——但光愤怒没用"] C --> D["LV4 转向勤奋逃离红海,构筑不可替代性——真正的分水岭"] D --> E["LV5 明知的勤奋哪里空缺补哪里——从心所欲不逾矩"] style A fill:#3a1c1c,stroke:#e57373,color:#fff style B fill:#3a2e1c,stroke:#ffb74d,color:#fff style C fill:#3a3a1c,stroke:#fff176,color:#fff style D fill:#1c3a24,stroke:#81c784,color:#fff style E fill:#1c2e3a,stroke:#64b5f6,color:#fff 二、五层地狱与天堂 LV1|懒到活着都成问题——这一层留不住人 理论上存在,现实中几乎没人能停在这里。 原因很简单:再懒的人也要吃饭睡觉,这是生理的铁律。 当你懒到把自己饿倒的地步,饥饿会立刻接管你的身体,把"逃离饥饿"瞬间转化为"活下去"的暴力驱动。 所以这一层是不稳定的——它自带一个弹射装置,会强行把人推向 LV2。你不需要努力离开它,饥饿会替你完成这件事。 这一层的教训是:纯粹的懒,连活着都做不到。人被迫劳动的第一推动力,是恐惧。 LV2|懒到刚好能活着——90%的人死在这里,而且死得心安理得 这是绝大多数人的段位,也是最危险的段位——因为它足够舒适,舒适到让你放弃挣扎。 刚好能活着,意味着你满足于温饱线上的生活:有口饭吃,有张床睡,还能刷刷手机。你不愿多付出一分,因为"活着"这个目标已经达成了。 但你有没有想过,你为此付出的代价是什么? 代价是:你的劳动彻底丧失了议价能力。 想想供需关系。当你只求"活着",你就等于向市场宣告——我可以被任何一个同样只求活着的人替换。而这样的人,遍地都是。你不是稀缺品,你是标准件。资本给标准件定价,从来不看你付出了多少,只看换掉你要花多少成本。而换掉你,几乎零成本。 这才是剥削的真相:剥削不是资本太贪婪,而是你太普通。 你和身边所有人懒在同一条水平线上,你们互为替代品,于是你们集体丧失了定价权。资本只是顺水推舟,开出一个和你真实价值南辕北辙的工资——你还得感恩戴德。 记住这句话:你穷,不是因为你不努力。恰恰是因为你和所有人一样努力。 LV3|懒到绝不承受剥削——觉醒的那一刻,愤怒是有价值的 某个瞬间,你突然看穿了这一切。 你意识到:问题的根源不在于我不够卖力,而在于我和所有人长得一模一样。 正因为大家都懒在同一层,资本才敢肆无忌惮地压价。工资和劳动价值的背离,不是资本坏,是这个位置上的人可以随便换。 这是觉醒。这份愤怒是宝贵的,它是你打破 LV2 舒适麻醉的唯一炸药。 但请注意——光有愤怒,你依然一无所有。 ...
主流算法 固定窗口计数器 每秒一个计数器,+1超过阈值就拒绝 缺点 0.51s 和 1.51s 之间产生2倍流量 滑动窗口 把时间切成更细的小格,滑动统计 缺点 解决临界问题,但是实现复杂 漏桶 请求进桶,匀速流出,桶满则弃 缺点流出速度恒定,扛不了正常的突发 令牌桶 匀速往桶里放令牌,来请求拿令牌,没令牌被拒绝 缺点允许一定突发
1. 屏幕高度必须与视线平齐 屏幕上缘应接近或略低于眼睛水平线,禁止长期低头使用设备。 2. 上肢支撑优先于肩部用力 键盘与鼠标位置需确保手肘自然下垂约90度,避免肩部抬起或前伸代偿。 3. 头部位置以“耳朵对肩”为标准 耳朵应位于肩峰正上方或略后方,一旦出现前伸即为错误姿势。 4. 静态坐姿持续时间不得超过45分钟 每30–45分钟必须进行至少30秒站立或活动调整,打断颈部静态负荷。 5. 禁止长时间塌陷式坐姿 避免骨盆后倾、胸椎塌陷及“窝在椅子里”使用电脑的姿势。 6. 每日进行基础颈深屈肌激活训练 执行下巴后收(chin tuck)10次,用于恢复头颈中立位控制能力。 核心原则 保持头颈中立位、减少前伸负荷、避免长时间静态固定。
什么是一般连拍和速度优先连拍? 在[速度优先连拍]模式下,当半按下快门按钮时,为第一张影像决定对焦,并且后续拍摄的对焦被锁定。