ECharts 数据更新的基本思路
ECharts 的核心使用方式是通过 setOption 更新配置。图表变化是否流畅、数据是否残留,往往取决于如何组织 option。 setOption 的合并行为默认情况下,setOption 会把新配置与旧配置合并。这对局部更新很方便,但如果新数据结构变化较大,也可能留下旧配置。 例如原来有三条折线,后来只剩两条,如果没有正确处理,第三条可能还保留在图表中。 使用稳定的 series id当图表包含多个 series 时,建议给每个 series 设置稳定的 id 或 name。这样 ECharts 更容易判断哪条数据对应哪条图形。 1234series: [ { id: 'pv', type: 'line', data: pvData }, { id: 'uv', type: 'line', data: uvData }] 稳定标识能减少更新时的错位。 需要清空时明确清空如果图表结构变化很大,可以考虑使用: 12chart.clear();ch...
REST 接口中的幂等性
幂等性指同一个操作执行一次和执行多次,对系统最终状态的影响相同。它是接口设计中很重要的稳定性概念。 HTTP 方法与幂等性按照语义,GET、PUT、DELETE 通常应是幂等的,POST 通常不是。 GET /users/1 多次查询,不改变状态; PUT /users/1 多次提交同一份完整数据,最终状态相同; DELETE /users/1 多次删除,最终都是不存在; POST /orders 多次提交,可能创建多个订单。 这只是语义约定,真正是否幂等还取决于实现。 为什么幂等重要网络请求可能超时、重试、重复提交。如果接口不具备幂等性,重试就可能造成重复创建、重复扣减或状态错乱。 因此关键写操作通常需要明确幂等设计。 常见方案一种常见做法是使用幂等键。客户端为一次业务操作生成唯一标识,服务端记录处理结果。相同幂等键再次提交时,直接返回已有结果。 另一种做法是让资源标识由客户端确定,例如 PUT /resources/{id},这样重复请求会落到同一个资源上。 幂等不等于无副作用DELETE 第一次执行可能删除资源,当然有副作用。但第二次、第三次执行不会继续产生新的状态...
Docker 镜像与容器的区别
Docker 入门时最容易混淆的是镜像和容器。简单说,镜像是静态模板,容器是镜像运行后的实例。 镜像是分层文件系统镜像由多层只读层组成。Dockerfile 中的每一步通常都会形成一层。分层的好处是可以复用,也方便构建缓存。 例如多个镜像都基于同一个基础镜像时,底层内容不需要重复下载。 容器是运行实例容器基于镜像启动,并在只读镜像层之上增加一个可写层。程序运行时产生的临时文件、修改内容通常会落在这个可写层里。 如果删除容器,这个可写层也会消失。因此需要持久化的数据应放到 volume 或绑定挂载中。 镜像不应该保存运行状态镜像适合保存程序、依赖、默认配置,不适合保存运行过程中变化的数据。这样才能保证同一个镜像在不同环境中行为一致。 构建与运行分离构建镜像时关注“如何得到可运行环境”,运行容器时关注“如何提供配置和数据”。这两个阶段分开后,升级、回滚和迁移都会更清晰。 小结镜像像模板,容器像进程实例。镜像负责可重复分发,容器负责实际运行,数据持久化则应交给挂载或外部存储。
Nginx location 匹配规则简记
Nginx 的 location 看似只是路径匹配,但前缀、精确、正则之间有优先级。理解匹配顺序,能减少很多配置上的误判。 常见类型常见写法包括: 12345location = /exact { }location /prefix/ { }location ^~ /static/ { }location ~ \.php$ { }location ~* \.jpg$ { } 它们分别表示精确匹配、普通前缀匹配、优先前缀匹配、区分大小写正则、不区分大小写正则。 匹配顺序简化理解如下: 先找精确匹配 =; 再找最长前缀匹配; 如果最长前缀带 ^~,直接使用; 否则继续按配置顺序检查正则; 正则没有匹配时,使用之前找到的最长前缀。 因此普通前缀匹配不一定最终生效,正则可能覆盖它。 root 与 aliasroot 会把请求 URI 拼到目录后面;alias 则用指定目录替换匹配前缀。二者语义不同,混淆时容易出现路径多一段或少一段的问题。 示例: 123location /sta...
Java 线程池参数怎么理解
线程池的价值在于复用线程、限制并发、管理任务队列。理解线程池参数,比记住某个固定配置更重要。 核心参数ThreadPoolExecutor 常见参数包括: corePoolSize:核心线程数; maximumPoolSize:最大线程数; keepAliveTime:非核心线程空闲存活时间; workQueue:任务队列; threadFactory:线程创建方式; handler:拒绝策略。 这些参数共同决定任务来了之后如何排队、扩容和拒绝。 任务提交后的流程一个简化流程是: 当前线程数小于 corePoolSize,创建核心线程执行; 核心线程已满,任务进入队列; 队列满了,尝试创建非核心线程,直到 maximumPoolSize; 仍然无法处理,触发拒绝策略。 因此队列类型会影响最大线程数是否容易生效。无界队列可能让任务一直排队,导致最大线程数很少被用到。 CPU 密集与 IO 密集CPU 密集任务主要消耗计算资源,线程数通常接近 CPU 核心数。IO 密集任务经常等待网络或磁盘,可以使用更多线程,但也不能无限增加。 判断线程数是否合理,最好结合实际指标:CP...
HTTP 缓存的几个基础概念
HTTP 缓存的目标是减少重复传输,让浏览器和服务器都少做无用功。理解缓存并不需要先记住所有头字段,先分清“强缓存”和“协商缓存”就够了。 强缓存强缓存命中时,浏览器可以直接使用本地副本,不需要向服务器发请求。常见控制字段是: 1Cache-Control: max-age=3600 它表示资源在 3600 秒内可以认为是新鲜的。对于带版本号的静态资源,例如 app.abc123.js,可以设置较长缓存时间。 协商缓存协商缓存会向服务器确认资源是否变化。如果没变化,服务器返回 304 Not Modified,浏览器继续使用本地缓存。 常见字段包括: Last-Modified / If-Modified-Since ETag / If-None-Match ETag 通常比 Last-Modified 更精确,因为它可以根据内容生成标识。 静态资源的版本化缓存策略最好和资源命名配合使用。文件内容变化时,文件名也变化;文件名不变时,内容也不变。 这样可以让静态资源使用长缓存,同时避免用户拿到旧代码。 HTML 与静态资源不同HTML 页面一般不适合设...
Java 中 equals 与 hashCode 的关系
equals 和 hashCode 是 Java 对象体系里很基础的一组方法。它们平时不显眼,但一旦放进 HashMap、HashSet 这类集合中,就会直接影响对象的查找与去重。 equals 表示逻辑相等默认情况下,Object.equals 比较的是引用地址。也就是说,只有两个引用指向同一个对象时才返回 true。 很多业务对象需要的是“逻辑相等”。例如两个对象的 id 相同,就可以认为它们表示同一个实体。这时就需要重写 equals。 hashCode 用于快速定位哈希集合不会一开始就逐个调用 equals。它会先用 hashCode 找到大致位置,再在可能冲突的位置上比较 equals。 因此有一条重要约定: 如果两个对象 equals 返回 true,它们的 hashCode 必须相同。 反过来不要求成立。两个对象 hashCode 相同,只代表它们可能落在同一个桶里,不代表它们相等。 常见错误只重写 equals 不重写 hashCode 是常见错误。对象在普通比较中看起来相等,但放入 HashSet 后可能无法正确去重。 另一个错误是用可变字段计算 has...
二分查找的边界条件
二分查找看起来简单,真正容易出错的是边界。循环条件、区间开闭、返回值含义只要有一处不一致,就会出现死循环或漏掉答案。 先确定区间语义二分查找常见两种写法:闭区间 [left, right] 和左闭右开区间 [left, right)。 闭区间写法中,left 和 right 都是可能答案: 12345678int left = 0, right = nums.length - 1;while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) return mid; if (nums[mid] < target) left = mid + 1; else right = mid - 1;}return -1; 左闭右开写法中,right 不属于搜索范围: 123456int left = 0, right = nums.length;while (left < right) { int mi...
在当前目录打开Cygwin的正确姿势
在网上找了一些解决方案,一般都是雷同的方法。对于一些细节并没有兼顾到,比如路径中存在空格的情况,比如根目录与非根目录的路径形式的不同。 改进之后的方案.bashrc 123456export _T=${_T//\\//} # replace backslash to fowardslashexport _T=${_T//\"/} # 如果目录带中文,传入的目录会在首尾加引号,如果无中文则不会加双引号。这里删除首尾双引号,归一处理if [[ $_T == "" ]]; then export _T="C:\cygwin64\home\xxx" ficd "$_T" 注册表:HKEY_CLASSES_ROOT\Directory\Background\shell\open in Cygwin\command 1c:\cygwin64\bin\mintty.exe /bin/env _T="%V/" /bin/bash -l 相关...
暴力而不失优雅地升级Hexo主题
对hexo页面排版的改动时常需要改主题目录里的文件,但主题也会升级,这意味着用户和主题开发者可能会改动相同的代码,如果不妥善管理代码,需要升级主题时,可能会很不优雅。本文以Next主题为例。 手动升级面对升级版本之间的改动,一种容易想到的方法是纯手动升级。这里有两个案例 Hexo 主题快速升级办法-知识沉言 手动保存主题改动过的文件如果你在themes/xxx主题文件有自定义的修改,请自行手动备份一下;如果你是大改的话,我也没有好办法 Hexo升级之坑-杨二小 断断续续折腾了两天,才升级成功。所以,如果有啥感想,那就是:没事别瞎TM升级!当然,如果一定要升级,最好做增量升级:另起炉灶,一项一项地加功能,这样好定位问题,也容易回滚。 看来手动升级不够优雅,容易采坑。 通过git升级为了避免手动升级,一个思路是采用git仓库管理主题目录,当主题升级时,采用git进行平滑升级。这看似优雅,却会引入另一个问题:如何在主博客仓库中合理管理一个子主题仓库?NexT Issue #932有很多讨论,也有一些解决方案,这里列出几个: 1 采用数据文件的方式参考数据文件的...