最新动态










- 《骑行密云水库》视频制作
上周六骑行密云水库,特意多带了一个手机,架在车把前方,拍下了整个旅程。真的是好不容易录的(手机还行,人不容易),所以很想剪一个视频出来,自己有点成就感,也想分享给家人朋友。 这是我第一次剪视频,是一次未知的挑战。这是一项工程,有明确的验收目标:内容上,表达骑行的所见和所想,质量上,要有精心的设计,能通过我自己的审美标准;有明确的交付时间:最晚本周日晚上,因为过了这个时间,就没意思了。 先做基本构思。素材主要是行路画面,所以自然想到《平凡之路》的MV,这首歌也符合那天的心境,这在骑行过程中就定好了。骑行是一个线性的过程,因此要有头、有尾,出发→到达→返程→到家,阶段明确,分镜总体按时间顺序编排。 周中做了一些准备工作,周六下雨,正式开干! 因为没有经验,全靠理性在摸索,所以周六干得很艰难。总结一下周六做对了的事情: 把素材完整捋过一遍,哪个视频,有什么内容、重要场景、重要画面,按时间顺序一一写出来。计算机领域这叫“索引”,这样后面查找需要的内容就有依据、效率高了。否则,素材茫茫多,无从下手。 放弃模仿韩寒的《平凡之路》MV分镜设计,因为除了歌曲和行路外,其实完全不同,并不适合。我重新单独听歌曲,按感觉对歌曲分段,写出哪一段适合对应我的哪一段,再细化到每句歌词、每段间奏的内容。 先粗剪出第一版再说。在大致符合设计思路的前提下,先粗略地把整首歌按合适的分镜断点都配上画面。第一版是一个骨架。没有这个骨架,想法是发散的、无穷无尽的,这通常是眼高手低干不成事的前兆。有了第一版,就收敛到了一个基线上,后面无非是慢慢改嘛,对可行性、进度都有了一个心理锚点。 周六晚第一版出来,简直惨不忍睹:歌词画面不搭,内容凌乱,不知所云;原始素材歪斜、难看,尤其是夜景,糊成一坨。累了一天,就干出了这么个玩意儿?我觉得,没戏了,可能这样的素材就是做不出来,可能我就是没有那个能力。 周日睡到自然醒,还是想再看一眼。诶?这怎么感觉,还有救呢?饭也不想吃了,接着干! 词画不搭,那就一点一点重新选画面。素材歪斜,那就旋转调正。素材不够,那就把其他日子拍的挪过来。夜景糊,那就加滤镜。骑速慢分镜短,那就加速。歌词全上画以为很费时,但分镜切好+规则样式其实很快。再做出片头,做出片尾,加上字幕,解决衔接问题。晚上9点,导出第24版时,终于定稿! 发布! 想象中是要搞个大片出来,实际上就是个非常普通的视频,但不管怎么说,它达成了我的工程目标,也是我在现有条件和约束下能做到的最好了。冯骥说,完成比完美更重要。所以,我还是觉得很开心。 剪映是个好软件,功能直观好用,不枉我给它充了一个月的会员。
- 骑行:密云水库
本次骑行是为六月的计划进行的模拟考试,目标是验证我有单日200公里的能力。 时间:5月30日周六。地点:密云水库。里程:110公里×2。时长不重要,均速不重要,完成就是合格。 去程 早上6点起床,7点出发,迎着已经热烈起来的朝阳,我一路向东北方向前进。林荫路、桥洞、城市路、立交桥、施工路、郊区路、河桥、山路,信号灯、车流、摩托、其他骑行者、行人,骑行的过程总是大同小异,不过,体验的就是这个过程嘛。 今日晴空万里,几无片云,密云密云,云不太密啊。阳光持续直射,炫目又烧灼,预报说最高35℃。经过一路的运动和暴晒,中午12点多,我感觉我已经有点中暑了。具体症状是,浑身乏力(也可能是因为体力消耗),有点畏冷(类似于感冒,这就不正常了),吸气时喉咙有寒冷刺激感(也类似于感冒),好在不算太严重,还能动。水库已经不远了,坚持住!上山慢得像爬,爬也要爬到! 下午2点,到达密云水库!榨出最后的体力飞驰穿过笔直的潮河主坝,我多想大喊一声“芜湖”,可发现嗓子喊不出来了。把车子停在一堵矮墙边,我已经没有力气做任何事了,只能也跟着瘫坐在墙根下。自拍一张,眼神都呆滞了。 整整休息了一个小时,才感觉缓了过来。好了,又一次把帽子扔过了栅栏,来时是体力相对充沛的114公里,去时已是一身的debuff,怎么回去,看你咯。 返程 多说无益,上车。 3点出发,仍然是正热的时候,刚压下去的中暑感又缠上身体。回程是西南方向,所以几乎是一路直面太阳,漫长的左堤路右侧甚至没有树荫。风不仅燥热,还是逆风,让本就不富裕的体力雪上加霜。两腿都在抽筋的边缘,只能用交替间歇式蹬车法,蹬几脚,溜一段,每公里均速从正常的二十、十几一度掉到个位数。从未如此期待落山的太阳下,越来越难听见Keep报新的公里数,回家的路似无尽般漫长。 “您已打破自己的最远骑行记录!“Keep告诉我,已经超过上次的160公里了。我随即在路边停了车,瘫软地坐在地上,因为我刚刚在冲刺,这次已经比上次(9小时50分)慢了,但我还是想冲一冲10小时以内,可惜,还是超了2秒。而也就是这个没什么意义的小目标才支撑着我来到这里,157公里的时候我就已经觉得必须停车了。我背对着马路坐在路肩,身后无数去市里的车辆呼啸而过。我真的,太累了,这就是我的极限了吗?我之前不停下来休息,是因为我实际上还能蹬下去,不管多慢,走起来就还有希望,停了就真的遥遥无期了。可是我现在,现在好像,好像真的,真的蹬不动了,真的没有一丝力气了。要叫货拉拉吗?可那样,160公里就白费了,下一次,我仍然要先走过那160公里,那时再止步于此? 休息了大约半个小时,起身,我还是不想放弃,只是得想想办法。高德显示,整好还有60公里,于是我给自己制定了这样的规则: 接下来,每10公里我们设置一个虚拟休息站,那么60公里就一共有5站,分别设在距终点49.9、39.9、29.9、19.9和9.9公里处。只允许在休息站休息,不允许途中休息。每到达一个休息站,可获得10分钟的休息时间。可以自由选择是否进站、站内休息多久,未休息的余额可以累加到后面休息。这个规则像是有神奇的力量(后面分析),最终,我以“两停“策略完成了比赛: 序号 距终点距离 分析 决定 休息时长 休息方法 剩余休息时长 1 49.9 身体还能撑住。现在已经握有10分钟了,心里开始有点底气了,把时间留给后面,可以一次性多休息会儿。 不进站 0 - 10 2 39.9 45公里左右时,腿就感觉快不行了,所以本站必须进站。这一站可以躺着休息,下一站就不一定了,所以稍微休息长一点(15分钟),但还是留5分钟备用。 进站 15 路边有石墩,躺在上面,手、脚悬空,腰有支撑,屁股压强小,最大化休息效率。 5 3 29.9 身体还能撑住。 不进站 0 - 15 4 19.9 到东三环了,身体状态恢复了很多,甚至可以连续蹬车了。19.9,交个朋友,助我到下一站。 不进站 0 - 25 5 9.9 身体状态还行,也许能直接冲刺,但右膝盖刚才突然反应了一下,以防万一,还是进站。 进站 10 在公园矮墙上躺着。 25 晚上11点半,农历十四的明亮月光下,我终于到家了。 牛逼的哥们儿 去程中,在顺义遇到一个骑共享单车的哥们儿,问我的车是山地车还是公路车,说他也准备买一个。然后你猜怎么着,我在水库又遇到了他,还是那辆小蓝车。我们不约而同地互道了一声,“好巧啊“。 后来回家之后,我还专门在地图上查了一下,单程将近50公里。还是你牛逼啊,哥们儿! 成果 打破个人记录!第一次上200公里!证明了我有实施计划的能力,考试通过! 五一的时候,我心血来潮,坐地铁,从最西北的俸伯站,到最西南的燕山站,将北京跑了个对角线。今天,我靠自己的人力,跑了个更长的对角线,哈哈! 感受与分析 今日最大的感受,就是艰难,艰难又狼狈。 印象最深刻的,当然就是最后60公里的“休息站规则“,感谢我最近在看F1,才想到这么个法子。分析一下,这个规则所谓的“神奇的力量“是什么。客观上,① 太阳下山,炎热和暴晒debuff逐渐解除;② 人的体能实际上并没有真正耗尽,只是冲刺那一下透支了。主观上,① 大任务分解成小任务,更容易执行;② 被动地被迫休息,变成了主动地选择休息,心理上更有主动权和控制感;③ 60公里是合适的,因为每到一站,剩余里程数都在平时的轻松可达范围内,始终会感觉快到了,如果是80、90、100+,则此规则行不通。 不管怎么说,我真的做到了。 6月1日周一OS:周六一模一样的无云晴天,去相邻的楼吃饭都觉得晒得难受。周六还是太莽了,没死在路上真是命大。经验与教训 这次戴了袖套,手没事,但头没做保护,脸晒黑了,后颈更明显,下次要注意脸和脖子的防晒。 长途骑行腰难受(难受到周一),可能是背了太多水(怕山里没法买),下次要注意腰水平衡,或者整个货架?
- 汉王Clear 7锦鲤使用体验
优点: 屏幕刷新速度很快,明显快过我之前的Kindle Oasis 2和文石 Poke 4S。 对称式,而非人体工学式,方便手捧着阅读、斜靠着阅读。 PDF用“适应屏宽”+“裁边”+“卷轴”,可以充分占满屏幕来显示PDF的内容,虽然限于屏幕尺寸,PDF的字还是小,但至少可读了。 缺点: WiFi信号较差,2.4G WiFi手机信号满格时,它只有2/4格。 不支持WPA3的热点,连不上,要改成WPA2。 打字反应慢,打快了会漏触,自带输入法和微信输入法都是这样。 PDF不支持横屏。 扫描版PDF不支持批注。 PDF的“OCR重排”功能不如推荐说的那么好用,重排后是文字+图片,没有字体,没有排版,不如只裁边看得舒服。 看大体积漫画(200MB+)时,偶尔点击翻页无反应。
- 骑行:居庸关+八达岭
准备 距5月4号的廊坊骑行也有两周了,本周六是时候要继续训练了。本次骑行的基本目标:保量,至少100公里。 最近在跑步减重,但是跑得不太对,左小腿肚疼,右小腿骨疼,豆包说,可不能再跑了嗷,所以周中就停了,但疼一时半会儿没法恢复,周六就这么上吧,骑车负荷没那么大,应该还行吧。 本来是准备环五环的,刚好100公里。可一查,五环没有辅路,得自己找路线。周五晚上画睡着了都没把路线画明白,周六起床已经是中午,那还是随便找个简单的路线吧,我把目光瞄向了城北。八达岭?往返160公里,我这个状态,是不是有点激进了?十三陵?往返120公里,跟廊坊一样,正好保量,那就十三陵。 看看天气,两个手机都跟我说下午要下雨,你们真是难得统一。不过再看周日,下一天,啊这。今天要是不去,明天就更不会去了,人泡汤和计划泡汤,选一个呗。 去程 还是人泡汤吧。随便吃了点儿,背上包,拿上充电宝,这就出发了。 穿越西边半座城,我一路向北。车轮从无数的大学、院所、园区、建筑、公园旁滚滚而过,杨柳毛毛少了很多,有一种花开遍了全城(后来我知道,那是月季),在人民大学的墙上尤为繁盛。雨水到来之前的北京,真是舒爽。 出北五环时,我谨记上次的经验,补充了几瓶电解质水,防止抽筋,然后走上了漫长的G6辅路。切记切记,档位调低,完赛第一。 来到昌平的一个大立交桥,好了,在你面前是一个分岔口:一,stick with the plan,去十三陵,近在眼前了;二,激进一把,去八达岭,你从来没到过这个距离,现在这个时间这个天气,天黑之前不一定能到,你可能什么都看不到,而返程,甚至可能今天(0点前)都到不了家了。 好吧,其实我压根也没犹豫。不到长城非好汉,那我骑到长城,也能算个好汉了吧? 五点,雨开始落下。我在一座桥下躲了一会儿,桥下还有一家三口,三辆自行车,真好啊。雨一直不停,想到后面还有很长的路,我还是怀着天黑之前到达的希望,又扎进了雨中。于是,从这里开始,我就没有一刻停止淋雨了。 开始进山。 过居庸关村,迎面来了一个骑行的大哥,两个湿人互相看了看。我猜他是从八达岭返回,我猜他猜我是去八达岭,都这个点儿了。没错的,大哥,我猜你猜我猜得对。 上山的路总是艰难的,蜿蜒曲折,不进则退。这路,跟上庐山的公路好像啊。要说跑步还是有点儿用的,至少让我长了点儿耐力。档位调最小了,喘气调最大了,一脚一脚地挪,推车是不可能推车的,还是要脸。 上山20公里,我的右大腿已经在抽筋的边缘了,不过,好歹是到了,终于到了,真的到了。七点,到达八达岭长城的登城口,天色尚明。 此时正好老妈打来视频,我没敢接,这个点儿,在深山里,说出来就不让人放心。 返程 没必要休息了,天黑了,赶快下山最要紧。车灯打开,下山! 20公里的下山,爽到飞起,几乎完全不用蹬车,我的右大腿又回来啦。但是车速还是要控制的,车道也不能乱走,雨天路滑,树叶下的山路已经黑了,对向还有刺眼的汽车,安全第一,安全第一。阴凉的山,湿透的我,狂风冷得我浑身颤抖。一辆MPV中的小姐姐问我,需要雨伞吗?我抹了一脸的水,笑了笑,不用了,谢谢。 又回到了居庸关,关楼和山上的长城,都已被灯光点亮,在暗色的天空和山峦背景上,耀眼夺目。这是我未曾预料到的美,也成了我今天最深刻的记忆。 出山了,剩下的60公里,全凭“回家的诱惑“——无论如何,回家就好。ABS式骑法(两腿各蹬4下,然后溜车一段),回家!档位调高(负荷更大,速度更快),回家!雨小了,汗补上,回家,回家,回家! 23:55,到家! 用家里话说,我是暖水提涨(浑身湿透到淌水)。 成果 刷新记录!160公里!而且,我又一次,没抽筋! 下一次直接模拟考试吧,而且我是不是可以尝试拍视频了?
- backend项目架构设计 - 执行时间分析
做一个复杂的数据计算需求,执行过程被拆分为几十个Service(服务)和Calculator(计算器)类,且在其中又调用了十几个基础数据的Service类。计算逻辑开发好后,结构清楚,但执行时间很长,需要做性能优化。那么,应该优化哪些地方,即哪些地方是性能瓶颈?这需要对执行时间做统计和分析。 计时 我们利用Spring的AOP功能实现对方法做执行时间计时。 例如,对于Service,编写如下切面类: @Aspect @Component @Slf4j public class ServiceTimingAspect { /** * 切点 * <p>切点为{@code com.company.project}包下任意层级的{@code service}包中的所有类的所有方法。</p> */ @Pointcut("execution(* com.company.project..service..*(..))") private void pointcut() {} /** * 环绕通知,执行并计时 * @param joinPoint 连接点 * @return 切点的返回值 * @throws Throwable 切点的抛出对象 */ @Around("pointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { // 执行并计时 var startTime = System.currentTimeMillis(); Object result = joinPoint.proceed(); var endTime = System.currentTimeMillis(); var duration = endTime - startTime; // 方法签名 var methodSignature = joinPoint.toString(); methodSignature = methodSignature.substring("execution(".length(), methodSignature.length() - 1); logger.debug("方法签名{}耗时: {}ms", methodSignature, duration); // 实参列表 var args = Arrays.toString(joinPoint.getArgs()); args = args.substring(1, args.length() - 1); args = args.replace("\n", "\\n").replace("\t", "\\t"); // 方法调用 var methodCall = methodSignature.substring(0, methodSignature.indexOf("(") + 1) + args + ")"; logger.debug("方法调用{}耗时: {}ms", methodCall, duration); return result; } } 日志 通过配置logback-spring.xml将切面类的日志同时输出到控制台和专门的计时日志文件: <!-- 输出到计时日志文件的Appender --> <appender name="TIMING_LOG_FILE" class="ch.qos.logback.core.FileAppender"> <file>log/timing.log</file> <encoder> <pattern>${FILE_LOG_PATTERN}</pattern> </encoder> </appender> <!-- 切面类的Logger --> <logger name="切面类所在的包名" level="DEBUG" additivity="false"> <appender-ref ref="CONSOLE"/> <appender-ref ref="TIMING_LOG_FILE"/> </logger> 统计 编写TimingLogAnalyzer类,通过main()方法执行,读取计时日志文件,统计每个方法签名、方法调用的执行次数、总耗时、最小耗时、最大耗时、平均耗时,然后将统计结果输出到Excel文件中。 分析 在Excel文件中通过排序、筛选、统计图等手段,分析出性能瓶颈的所在,进而有针对性地去做性能优化。 功能增强 对Mapper、Calculator、Controller或者其他类做计时切面类。尤其是Mapper,可以用于分析缓慢的数据库查询。 通过配置和@ConditionalOnProperty控制切面类的装配,线上关闭计时,本地也只在需要分析时才开启计时。