和焦虑做朋友

焦虑的产生焦虑产生来自于恐惧,恐惧是对当下刺激的应激反应,焦虑是对未来刺激的应激反应。当我们在碰到一些严重刺激我们感官的事情时,杏仁核会接收到恐怖和惊惧,那么海马体会把这些感受记录下来。紧接着交叉神经也会启动,血压飙升、心跳加速都可以让你牢牢记住这个经历,如果它是足以对人身造成危险的情况,那么你下次很大概率会自动躲避。 换句话说也就是说,焦虑是保护自己的。 现代社会中,我们不需要再面对大量的恐惧了,但是筑巢本能依然存在,海马体依然保存了相关的能力,今年年初上海的疫情,让我们对基本的衣食住行感到焦虑,因为,平时唾手可得的食物,在疫情期间获取是如此的困难,这些恐惧让我们的海马体记录下来,很长时间内,我们会对未来产生焦虑,这些焦虑是良性的,保证我们生存的本能,在漫长的进化过程中,没有焦虑的人很可能因为没有储存过冬的食物而灭绝,我们能延续到现在,很大程度上是因为祖先适度的焦虑。 焦虑不可能完全消除焦虑的本质是恐惧的提前,是对未来的不确定性的担忧,这就意味着它是不可能被消除的。它不是现代人特有的, 物质极大丰富的年代反而更加剧了这种焦虑,我们看似拥有很多东西,世纪上都是空中楼阁,我们过于依赖外界,这让一切变得不确定,不确定产生焦虑。 面对现实,承认焦虑的存在,我们才有可能和焦虑做朋友。坦诚是一个人最好的品质。特别是对自己坦诚,大部分时候,我们喜欢自欺欺人,坦诚可以让我们面对问题本身,一旦承认了问题的存在,我们才有解决问题的可能,我们才能变得更好,这也是实事求是的来源。 一个焦虑的消失会伴随着另一个焦虑的诞生,就像叔本华说的,人是在无聊和痛苦之间摇摆的动物。

散文随笔

Spring @Transactional是如何工作的?

Spring事务使用Spring配置事务还是挺简单的,第一步创建事务管理器TransactionManager,然后在配置中增加一个@EnableTransactionManagement就可以启用Spring事务了,所以关键类就是@EnableTransactionManagement 1234@Bean public DataSourceTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } 我们可以看到@EnableTransactionManagement 上实际上是import了TransactionManagementConfigurationSelector类,在这个Selector中实际import了两个配置类: AutoProxyRegistrar ProxyTransactionManagementConfiguration 1234567891011121314@Override protected String[] selectImports(AdviceMode adviceMode) { switch (adviceMode) { case PROXY: return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}; case ASPECTJ: return new String[] {determineTransactionAspectClass()}; default: return null; } } 下面我们来根据这个入口来分析一下Spring是如何处理事务的:

源码解析

使用chezmoi管理dotfiles

为什么要管理dotfiles?dotfile是对自己的软件配置文件的总称,如果有多台开发设备的话,我们需要在不同的电脑上保持同样的配置,我们对工具的使用不是一成不变的,而是随着时间不断演进的,日常使用的过程中,会不断修改dotfile让工具越来越顺手,这时同步dotfile就变得非常重要了,你的工具的行为在多个平台上应该是一致的,就像VSCode自带的setting 同步功能一样。 dotfiles管理的痛点 dotfile总是分布在不同的位置,想把他们汇总在同一个位置非常不方便,使用软连接之后,用github管理又非常不便。 配置文件的修改不能及时同步到github 多个设备可能跨平台,配置文件可能是不一样的 相同的平台,不同的设备也有差异化的配置,比如工作电脑和自己私人电脑,有一些配置肯定是不一样的 密码管理器,选择自己合适的密码管理软件() 什么是chezmoi?chezmoi是一款使用go语言编写的跨平台的的dot配置管理器,它是一个法语单词,意思是家,读作 /ʃeɪ mwa/ (shay-moi) chezmoi的工作原理很简单: 它使用一个working copy来管理dotfiles,chezmoi负责对working copy和home directory 进行同步,然后使用git来管理 working copy和remote repo的差异。

工具效率

理解Jvm Class文件结构

理解Jvm Class 文件结构Class 文件结构如下: 123456789101112131415161718ClassFile { u4 magic; //Class 文件的标志 u2 minor_version;//Class 的小版本号 u2 major_version;//Class 的大版本号 u2 constant_pool_count;//常量池的数量 cp_info constant_pool[constant_pool_count-1];//常量池 u2 access_flags;//Class 的访问标记 u2 this_class;//当前类 u2 super_class;//父类 u2 interfaces_count;//接口 u2 interfaces[interfaces_count];//一个类可以实现多个接口 u2 fields_count;//Class 文件的字段属性 field_info fields[fields_count];//一个类可以有多个字段 u2 methods_count;//Class 文件的方法数量 method_info methods[methods_count];//一个类可以有个多个方法 u2 attributes_count;//此类的属性表中的属性数 attribute_info attributes[attributes_count];//属性表集合} 下面的这个图更加直观: 使用010 Editor 打开 Hello.class 可以更加直观的查看

技术随笔

SpringBoot是如何启动的?

Spring Boot 启动SpringBoot的启动类很简单,只需要调用SpringApplication的run方法即可,这篇文章来分析一下SpringBoot的启动类SpringApplication初始化的过程。 123public static void main(String[] args) { SpringApplication.run(Application.class, args); } 在SpingApplication 中 初始化了一个SpringApplication, 参数是当前SpringBoot启动的类 123public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { return new SpringApplication(primarySources).run(args); } SpringApplication初始化 从classpath推断 webApplicationType 设置Initializers 设置Listeners 推断main class,主要用于log print以及banner print 123456789public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); this.webApplicationType = WebApplicationType.deduceFromClasspath(); setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass(); }

源码解析

Spring是如何加载BeanDefinition的?

Spring Bean生命周期中,BeanDefinition是最重要的部分,在初始化和实例化Bean之前,首先要把所有的需要Spring管理的Bean对应的BeanDefinition加载到Spring容器中,这一步非常关键,因为BeanDefinition是Bean关联的元数据,这一篇文章就以AnnotationConfigApplicationContext来分析一下Spring容器是如何加载BeanDefinition的。 第一阶段:扫描Class文件加载BeanDefinition123456public AnnotationConfigApplicationContext(String... basePackages) { this(); scan(basePackages); refresh(); } 我们先以package的方式来分析,初始化AnnotationConfigApplicationContext的时候会scan对应的包路径,然后进行refresh scan的动作是在ClassPathBeanDefinitionScanner的doScan方法中完成的,主要任务是查找classpath下面的Class文件,判断是否为Bean,然后生成BeanDefinition。

源码解析

微信读书Obsidian实现二维码扫描登录

背景前几天写了个Obsidian微信读书的插件GitHub - zhaohongxuan/obsidian-weread-plugin,在B站上发了一个视频学了3天typescript写了一个微信读书的Obsidian插件_哔哩哔哩,最初版本是需要手动从控制台复制Cookie设置到设置界面才能使用的,很多B站网友给我私信说获取Cookie有问题,虽然在readme里已经写的很清楚了,但是对小白来说可能这也是个比较困难的步骤,所以我在想是否可以实现二维码扫码登录呢? 思路因为Obsidian其实也是个浏览器,所以理论上是可以打开浏览器窗口来展示扫码登录界面的。只要load到微信读书的扫码登录界面,然后intercept到请求的header拿到Cookie就可以了,然后后续只要被动刷新Cookie有效期即可。 所以问题就被分成了三部分: 展示二维码扫码框 intercept 登录操作获取到Cookie 将Cookie设置到setting 中

obsidian

微信读书Cookie自动延期机制分析

HTTP Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的HTTP协议记录稳定的状态信息成为了可能。 分析Cookie登录之前在进入到weread.qq.com的时候,就已经存在Cookie信息了,只不过一部分的Cookie信息是空的,下面是扫码登录之前的Cookie信息:

obsidian

使用Middle Server解决浏览器CORS跨域问题

问题产生最近学了Typescript写了一个Obsidian微信读书的插件Obsidian Weread Plugin,在写插件的过程中需要跨域请求r.qq.com来获取微信读书的书摘和想法。 使用axios在vscode中运行api测试的时候是好的,在obsidian中产生了CORS的问题,这是因为Obsidian本质上是一个Electron的app,本质上也是一个浏览器,所以才会出现跨域问题。 关于CORS的文章已经很多了,推荐参考Mozila CORS,作为一个后端开发,CORS 并不陌生,,对于Spring全家桶用户来说,就是几行@CrossOrigin的配置问题,但是这一篇文章提供的是前端视角来解决CORS的思路,也就是说对服务端不可控时如何处理? 解决思路我们都知道CORS本身只是对浏览器才会限制,所以可以跳出来使用代理服务器来解决问题,这里刚开始,我建立了一个Springboot的Web项目专门转发来自Obsidian的请求,将请求转发到r.qq.com,这样能够正常工作,但是也印出来了另外一个问题: 每次使用Weread插件的时候,我都需要把SpringBoot项目启动起来,显然不够优雅。特别是后面插件上架了Obsidian的社区市场之后肯定更不行,你不可能要求用户自己再额外下载一个服务器来运行。 那么是否可以找到一个可以在前端使用的middle server呢? 答案是可以!那就是http-proxy-middleware

obsidian

10款插件让你的Obsidian更加好用

Obsidian 是一款非常优秀的双链笔记软件,用它可以很方便的来管理自己的笔记,打造自己的数字花园(Digital Garden),虽然和Roam等纯粹的Outliner型笔记不太一样,它基于纯文本md文件,且支持文件夹,给了一些用户选择的自由,最重要的是启动速度很快(特别是和Notion相比,虽然是基于Electron的,不知道用了什么黑魔法) 同时Obsidian也是一款非常好用的写作软件,支持Live Preview的模式,类似于Typora的效果,个人感觉体验很好。 Obsidian是以Plugin化的形式设计的,很多核心的功能也都是以Plugin的形式出现的,这给了用户自由定制的空间,当然这也提高了上手的难度,无形中劝退了不少人,但是Plugin的形式会让这个软件生命力得到释放,社区的优秀的插件数量很多,用户可以根据自己的喜好自己定制自己的Obsidian,我想这也是Obsidian最吸引人的地方之一。 下面就介绍10款我平时用的最多的第三方插件,可以让你的Obsidian更加易用。 外观插件

obsidian
123459

本站由 Hank Zhao 使用 Stellar 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
本站总访问量