爱大客 - 2024年7月
type: channel
link: https://www.idarc.cn/index.php/2024/07/
description: Every piece of all creatures in this freezing world, are racing for freedom.
items: 看对咒符的解释有感
items: 油猴学习tampermonkey
items: 对网站进行测试的工具,哪个比较好用?
items: 检测爬虫特征的网站
items: 对分页和瀑布流的UI呈现的再次理解
items: 用jest测试微信小程序
items: 刘国梁备战巴黎奥运前接受采访说的几句话, 反传统但适合于任何事
items: 自定义微信小程序导航栏
items: 学习小红书
items: C语言Struct+Flash实现类似JSON配置文件的方式

看对咒符的解释有感
type: item
date: 2024-07-24T19:18:01+08:00
description: 【符咒原理-哔哩哔哩】 https://b23.tv/03OxEjN 我的理解一生二、二生三、三生万物，这些数字是带有单位的。一是一维线段，二是线段的二个方向，三是线段的左中右三个端点，也可以视为一个中点＋二个方向，此即一生二二生三。三生万物呢？就是一个维度（包括二个方向三个点）叠加上其他维度，生成了万物。此维度，既可以是几何空间的维度，也可以是时间维度、以及其他的任何维度。以最简单的两个维度相叠加，中点重合、相互垂直，共一个中点、四个方向，即为五。那这个五，其实就是直角坐标系，也可以是一个二维平面。五＝直角坐标系＝x轴＋y轴＋原点。两个轴代表不同维度，这个坐标系就可以表示各种概念，也就是我们在Excel和各种统计学中看到的折线图、柱形图、散点图……用于表示GDP增长、股票涨跌、企业竞争……维度从一维到再二维增加到更多维度，就是三生万物。 十和廿不太理解老师所讲，只能说下自己的理解。将一个二维概念——平面作为基础，则两平面相交为十，相交于一条直线。这似乎变成了三维概念，但我认为不是如此，因为三维概念应是七，即六方向＋一原点，但是十＝五＋五，即两个独立系统有各自的维度，又相互关联，确实与父母两人相互独立又关联交合很像。此处“交合”应为广义的，不限于性的交合，也包括生活方方面面的交合，与此同时两人又有各自的独立性。扩展一些，可解读为任何人与人之间在生活上的共同交集。廿似乎能解读为相互平行的平面？套用在人这个维度上，也就是相互之间没有直接交集的人，而中间一横，代表了中介人，即人与人之间即使没有直接接触，也是通过其他人连接成一个整体。人与人如此，万事万物亦是如此。 关于咒，老师说咒是口号，我理解还有一个接近的概念：座右铭。我们都知道口号光喊是没用的，重要的是行动，座右铭也是如此。说到底，古人门上贴的咒语、现代墙上刷的口号、桌子上摆的座右铭，都不只是喊喊而已的，它们的作用是时刻激励自己行动起来去改变自己。然而，很多人、甚至多数人，对待它们都只是喊喊而已，甚至喊都不喊，摆在那里就期望生效，其实只是让咒语、口号、座右铭承担了自己无法行动的愧疚。这个时候，桌上的座右铭、墙上的口号就和现代人不明所以的咒、符一样，变成了单纯的精神寄托、甚至是迷信了。咒、口号、座右铭上所写，都是自己的心愿，是所想要达成的自己，如何达成？挂墙上就能达成吗？是念。念咒的念字，是心字底，如果只是嘴上说说而不行动，就是心口不一，就不叫念。心口一致，就是知行合一，长期坚持，就是定力，正是因为在自己在自己的心愿上长期坚持，知行合一，才会产生法力：量变到质变，达成心愿，产生奇迹。

油猴学习tampermonkey
type: item
date: 2024-07-20T22:02:00+08:00
description: 希望用油猴做一些自动化的工具. 不用自动化测试软件的原因是特征都能被浏览器和页面检测出来, 所以这就存在一些风险. UiBot RPA虽然也可以, 没有检测痕迹, 但一是感觉软件太重了, 二是只能解决一些简单的Web上的问题, 很多时候复杂的问题如shadowRoot还需要配合js代码注入, 三是Uibot的代码编辑页实在有点难用,仿VB语言的算法也实在不太适应,尤其是不等号<>, 还有赋值和比较都是=不区分, 四是缺乏第三方库. 先推荐一个教程, 据说是中文唯一写的好的. https://github.com/scriptscat/tampermonkey-learn-guide 油猴官方可以说没有教程tutorial, 只有按字母序排列的API的说明. 虽然会JS上手也能写, 但只有明白额外的API才能进阶高级, 感觉有点像是electron, 不知道油猴是不是能实现类似electron的效果? 油猴名字 油猴这个翻译其实是grease monkey, 代码里简称的GM就是. 而tamper monkey是破坏猴的意思. // @ 最前面的注释部分, 以// @开头的其实都是给油猴看的代码, 类似于预定义, 是和油猴交互的关键. 其中最重要的一定要改的部分呢列出来. //@命令 子命令 解释 //@name 名称 脚本名称 //@match 网址 匹配网址, 也就是在哪个网址运行. 支持通配符* // @grant none 脚本直接注入window环境, 同时也不能使用GM_*命令了,所以一般不用 - unsafeWindow 直接使用页面中的任何脚本. 这就会打通页面和本地,理论上页面可以窃取本地内容并操控本地的一切. 脚本中的window需要替换为unsafeWindow - GM_* 申请指定的GM函数权限.页面window环境需要用unsafeWindow访问. - GM_xmlhttpRequest 允许跨域请求API - GM_setValue/ GM_getValue/ GM_deleteValue/ GM_addValueChangeListener/ GM_removeValueChangeListener/ GM_listValues 设置/获取/删除/监听/停止监听/列出本地键值对 - GM_registerMenuCommand /GM_unregisterMenuCommand 在油猴按钮上注册菜单 - GM_addStyle 增加 - window.onurlchange/.close/.focus 这三个window权限需要grant声明才能用 // @run-at document-start 在document加载时就尽快调用脚本(比页面脚本更早) context-menu 右键增加tempermonkey菜单,子菜单为本脚本名称, 点击运行 // @connect 网址 允许被GM_xmlhttpRequest请求的网址 // @require js文件URL#md5=xxxx 加载外部js资源文件并附带md5校验.引入油猴环境还是页面环境要看@grant定义. 也可以通过在html中插入script的方式来引用 // @resource css css文件URL 加载外部css 常用js代码部分 在html中增加元素 let div = document.createElement("div"); div.innerHTML = 'span1span2'; // 插入到页面的body中 document.body.append(div); 在html中增加按钮并监听 监听单个元素 let btn = document.createElement("button"); btn.innerHTML = "按钮文字，其实也可以写html，变成下面的样子(不过谁用按钮来包那么多html标签呢)"; //innerText也可以，区别是innerText不会解析html btn.onclick = function () { alert("点击了按钮"); }; document.body.append(btn); 监听多个元素 let div = document.createElement("div"); div.innerHTML = 'span1span class'; div.onclick = function (event) { if (event.target.id == "span-1") { alert("span-1被点击了"); } else if (event.target.className == "sp") { alert("sp这一类被点了"); } }; do…

对网站进行测试的工具,哪个比较好用?
type: item
date: 2024-07-19T19:42:00+08:00
description: 传统上有很多, 但有的太老,有的太难. 比如Selenium. 微软新出的playwright学习曲线也比较陡峭. 谷歌的puppeteer, testcase似乎更容易些. 然而最近比较火的是cypress, 基于node, 据说非常容易上手. 其实,我觉得油猴是否也可以用来写测试, 说不定也挺好用. 油猴就相当于在F12里写js. 但cypress的好处是可以自动等待页面或元素的加载. 但是cypress会被https://bot.sannysoft.com/检查出正在使用WebDriver, 也就是可能被识别为爬虫. 浏览器自身也会识别出来. 如用edge做cypress的时候, 会提示正在被自动测试软件控制. 另外UiBot creator打开https://bot.sannysoft.com/也不会被检测出任何问题.

检测爬虫特征的网站
type: item
date: 2024-07-19T19:35:29+08:00
description: https://bot.sannysoft.com/ 这个网站可以检查是否有不同于正常浏览器的爬虫特征. 如果要爬取网站数据则要非常注意了. 参考文章https://cloud.tencent.com/developer/article/1755512

对分页和瀑布流的UI呈现的再次理解
type: item
date: 2024-07-18T17:09:00+08:00
description: 之前对分页和瀑布流的理解比较简单, 就是手机滑动更适合瀑布流而电脑点击更适合分页. 今天才发现自己想简单了. 确实, 电脑上鼠标拖拉和滚动都不如手机上的手指滑动操作方便.上滑就特别适合加载新的数据. 但是,数据呈现的目的是不同的,两种方式各有优劣. 虽然瀑布流在手机上发扬光大, 但两者不是以手机或电脑来区分的. 我最近做的小程序, 需要呈现很多数据, 并且这些数据还需要增删改查. 因为是手机用, 我想当然认为瀑布流体验更好(当然实现难度也大), 就选择了用瀑布流. 然而近期发现一些问题, 用户反馈有时候数据会乱, 常常是重复. 查了下不是数据库的问题, 而是界面呈现的问题. 当然这种情况重新进入小程序也能解决. 我增加了一些控制, 在从数据库取数据的时候禁止用户操作, 但只解决了一部分问题. 最近打算用js面向对象的方法重构这部分代码, 写到增删改查的时候想到了这个问题: 在UI设计中, 瀑布流的方式是否适合呈现有大量数据的增删改查的页面? 如果增加了一个数据, 需要考虑这个数据增加的位置. 如果增加的数据排在前面已经显示的数据中, 那么就要重新请求已显示的数据. 但数据库的查询是按分页进行的, 我应该请求哪些分页? 似乎从数据增加位置之后的分页都要请求. 那么新数据增加在第几页? 需要计算,且计算结果必须和数据库自己的排序计算结果一致. 如果请求这之后的所有分页,有可能数据量非常大. 而且界面现在显示了N页, 增加1条数据变成了N页+1条, 而数据库是按页请求, 这样又不对齐了, 显示的最后一条数据要么从显示中删除, 要么再请求一整页. 删除有同样的问题. 修改操作如果修改的是排序的依据, 也存在新数据排到了哪儿的问题, 新旧位置之间的数据都要更新,或者用算法保持与数据库端一致. 这个逻辑就会变得复杂. 根源是: 数据库是按照分页方式请求的, 前端的增删操作导致前端数据和数据库数据无法对齐. 需要大量操作使两端对齐, 耗费本地计算和带宽, 感觉很不经济. 用分页就解决了, 非常简单, 增删改查后, 只要再次请求当前页就好了!即便是删除数据导致当前页消失, 也很容易计算到最近还存在数据的页是第几页. 这个问题抛给了metaso和gpt4o,两者都给出了否定的回答, 都指出分页更适合. 根据metaso给出的链接参考: https://blog.csdn.net/weixin_64051447/article/details/129420444, 其中有一个引文很重要: 滚动是延续，而点击是决定。—— Josh Porter 瀑布流就是为了不断地让用户看新的东西(新数据不断延续没有终点), 而点击是用户自己决定要看哪一部分东西. 所以瀑布流适合给用户不断地灌输新的数据, 而分页适合让用户管理数据. 贴一下gpt4o的回答, 我觉得总结得挺好 gpt4o的回答 在UI设计中，瀑布流（也称为无限滚动）是一种常见的布局方式，尤其适用于展示大量内容，例如图片库、社交媒体动态等。然而，这种布局方式在某些场景中可能并不合适，特别是在需要对大量数据进行增删改查（CRUD操作）的页面上。 瀑布流布局的优势： 用户体验：用户可以不间断地浏览内容，不需要经过分页的过程。 视觉吸引力：对于展示图像、视频等多媒体内容时，瀑布流能够更好地利用屏幕空间，看起来更加美观。 加载效率：通过懒加载技术，可以动态加载内容，从而减少初始加载时间，提高性能。 在增删改查页面中使用瀑布流可能的问题： 可查找性差：当用户需要查找特定数据时，瀑布流不如分页结构直观。无限滚动让定位特定记录变得困难。 数据管理复杂：频繁的数据增删操作可能导致数据的顺序和显示出现问题，需要复杂的逻辑进行维护。 浏览状态难以保存：用户在进行编辑后需要返回列表时，不容易恢复到之前的浏览位置，这会影响用户体验。 性能问题：随着数据量增加，长时间滚动会占用更多内存，可能导致性能下降。 适合增删改查页面的替代设计方案： 分页设计： 每页显示固定数量的数据，便于管理和查找特定记录。 提供清晰的导航条，让用户能够快速跳转到不同页码。 列表视图和表格视图结合： 使用表格视图提供清晰的数据结构显示，便于排序和筛选。 提供简单直观的数据操作按钮，例如新增、编辑或删除。 搜索和筛选功能： 提供强大的搜索栏和筛选条件，让用户能够快速找到所需数据。 动态更新结果，提高交互效率。 分区加载： 结合懒加载技术，仅在用户需要时才加载更多内容，但采用明确的分段结构，而非无限滚动。 综上所述，对于有大量数据且涉及频繁增删改查操作的页面设计来说，更建议采取分页设计、结合列表和表格视图，以及提供强大的搜索和筛选功能来提升用户体验。瀑布流布局虽有其独特优势，但在这种场景中并不是最佳选择。

用jest测试微信小程序
type: item
date: 2024-07-16T17:47:00+08:00
description: jest也是微信官方推荐的. 最简单的方式: jest安装后, 在目录下运行jest就可以. 它会搜索当前目录和所有子目录,并运行*.test.js结尾的所有测试,并汇总. 对于微信中的一些全局模块如wx, 需要mock. 在测试目录下建立__mocks__/目录, 所有要mock的都放在这儿. 如放个wx.js 在*.test.js中, 对全局的wx赋值global.wx=require('__mocks__/wx.js'). wx.js使用module.exports导出即可. 除了自己直接写mock模拟的函数外(如写一个wx.cloud.database = function mockFunc(){}的mock函数), 还可以用jest的mock函数const mockFunc = jest.fn(函数体);wx.cloud.database = mockFunc. 这样被mock的函数就会自带统计和记录功能. 如: 统计mock函数被调用的次数 mockFunc.mock.calls.length mock函数第n次调用时的第x个参数值 mockFunc.mock.calls[n][x] mock函数第n次调用的返回结果 mockFunc.mock.result[n].value mock函数最后一次调用的第一个参数 mockFunc.mock.lastCall[0] 对class的mock, 同样可以使用new const myMock1 = jest.fn();const a = new myMock1(); mock函数定义每一次的返回值,并且尅循环调用 mockFunc.mockReturnValueOnce(10).mockReturnValueOnce('x').mockReturnValue(true) mock模块的异步Promise返回值 import axios from 'axios'; jest.mock('axios'); const users = [{name: 'Bob'}]; const resp = {data: users}; axios.get.mockResolvedValue(resp); mock一个模块的部分函数和值

刘国梁备战巴黎奥运前接受采访说的几句话, 反传统但适合于任何事
type: item
date: 2024-07-10T15:23:41+08:00
description: 五块金牌是留给勇敢者的, 智慧者的, 发挥最好的人才配得上. 阅读理解: 勇敢和智慧, 即胆识. 主观的胆识才能遇到和抓住客观的机遇. 发挥最好, 也就是说能力最强并不能拿到冠军, 要临场发挥最好. 也就是说, 我们自己每个人恃才傲物, 觉得自己能力很强, 但只有在实战中发挥出来, 才能赢. 你面面俱到, 练得没有漏洞是不可能的, 只是在这些当中, 能够提炼出重点, 把这些得分手段精益求精, 把短板,把对手抓你的地方有所突破, 有所改善. 阅读理解: 面面俱到没有漏洞等于不可能. 所以没有人是完美的, 不要完美主义. 那要怎么做? 要把重点的得分手段去精益求精, 把短板(是指对方攻击自己的点)有所突破和改善. 这和木桶理论有一点矛盾, 或者说, 和用木桶理论作为解释一切的手段有矛盾. 木桶理论说最短的木板决定装水的容量, 所以要把所有的短板都补长, 所以要方方面面每个木板都做高, 做完美. 木桶理论有什么问题? 木桶是装水的, 不让静态的水流失的手段,所以木桶理论仅仅是防御静止的成果流失的手段, 只守而不攻, 并且是不去区分地防守. 个人资源是有限的, 环境是动态变化的, 而完美是不可能的, 把所有资源都投入防守, 面对动荡变化的环境, 最后只会成果越来越少,就像拎着装水的木桶在疾驰在颠簸路面上疾驰, 木桶上下翻滚, 然后我们的精力却全部放在修补木桶的短板上. 回到刘教头的话, 短板只能是有所突破和改善就很好了, 并且要补对手攻击自己的短板, 如果自己知道的弱点而别人不知道, 无法攻击也就无所谓去弥补. 面面俱到不可能, 要加强得分手段, 也就是要攻击对方, 要得分, 要开源, 而不是只是固守现有的成果. 所以, 强调木桶理论很容易故步自封陷入完美主义, 防御不存在的假想敌. 开源节流, 不能只节流不开源. 并且要突出自己的优势去开源, 去最大可能地发挥优势主动去抢夺(市场/资源/分数). 对于短板的修补要有针对性, 争取突破改善, 而不是要把短板做到最好. 短板之所以是短板, 就是自己天生或习惯弱于对方的, 补短板是事倍功半, 要补, 但要在自己有限的资源下看性价比. 会打球和会赢球是两码事 阅读理解: 能力强和能成功是两码事. 自己很强, 会很多事情, 很勤奋, 但就能成功吗? 两码事. 所以不要总是想着自己多强,或者把资源都投入让自己变强. 是不是很反传统? 除了变强,还要去赢. 强为什么不等于赢? 还是因为"强"是静态的,是此时此刻的一个状态, 而"赢"是动态的, 是竞争,是争取, 是随机应变. 如果不能随机应变,发挥自己的强, 适应竞争的环境,打败现实的对手(而不是想象的不存在的对手). 在赛场上的时候, 侥幸和犹豫, 想赢怕输, 这是失败的根本.宁肯坚决地错,也不犹豫地对. 因为你坚定下来的东西一定是你的认知. 阅读理解: 坚决地错, 很反传统. 传统有道是"三思而后行",但这未必是对的. 坚决地错和犹豫地对有什么根本区别? 坚决就是出自自己的认知, 犹豫就是混杂了别人的想法. 因为对别人的想法理解不通透, 所以即使是对也不知道为什么对, 又因为与自己想法的冲突, 因此犹豫.但在赛场上, 在战场上商场上, 一是没有时间给你犹豫, 二是没有足够的信息给你犹豫, 在那一刻必须做出尽快的决定, 无论对错. 如果是错的, 也是事后有了结果,有了充足的时间再去分析, 然后纠正的改善的是自己的认知, 而不是去简单听从别人的意见.所以, 坚决地错, 就是坚定执行自己的认知, 即便是错误的, 也是改善自己认知的机会. 如果没错过, 也就不可能提升自己的认知. 如果你在犹豫的时候,其实你怀疑的是自己,把位置摆低,去拼这五个项目,而不要去守. 阅读理解: 去拼,不要去守. 是换个方式讲上面说的得分手段精益求精. 得分就是要进攻, 进攻才能开源, 开源才有节流的资本, 才有能守的对象. 然而, 在激烈的竞争中, 主动进攻胜于被动防守. 被动防守总是容易消极的, 盯着自己的错误而不是别人的错误, 只能防止资本的减少而不能增加资本. 实现梦想,不留遗憾, 相信自己,相信团队. 阅读理解: 这句话虽然是末尾的一句祝福打气话, 但是也是再一次强调了前面说的话. 实现梦想不留遗憾, 也就是要去拼, 做自己想做的. 相信自己也就是要坚定和实践自己的认知. 相信团队, 做很多事情都不是一个人能完成的, 如果是一个团队去做, 要彼此信任才能减少不必要的内耗.

自定义微信小程序导航栏
type: item
date: 2024-07-10T15:10:28+08:00
description: 默认的导航栏NavigationBar不支持触摸事件, 需要自定义导航栏. 官方社区有个文档可以参考https://developers.weixin.qq.com/community/develop/article/doc/000a8c989307888cbe1abbf675f413 以下是gpt4o的回答. 在微信小程序中，原生的导航栏（通过 navigationBarTitleText 等配置项定义的顶部标题栏）本身不支持直接添加点击事件。不过，你可以采用一些变通的方法来实现类似的效果。 自定义导航栏 你可以通过自己编写一个自定义导航栏组件来实现点击事件。这通常涉及隐藏原生导航栏，并在页面顶部放置一个自定义视图组件。 隐藏原生导航栏 在 app.json 或单个页面的 json 文件中，将 navigationStyle 设置为 "custom"。 { "navigationStyle": "custom" } 创建自定义导航栏 创建一个自定义组件，例如 custom-navbar: custom-navbar.wxml {{title}} custom-navbar.wxss .navbar { height: 40px; background-color: #fff; display: flex; justify-content: center; align-items: center; } .navbar-title { font-size: 18px; } custom-navbar.js Component({ properties: { title: { type: String, value: '默认标题' } }, methods: { onTitleClick() { // 自定义逻辑，比如跳转或者弹出提示等 wx.showToast({ title: '标题被点击了', icon: 'none' }); } } }) 在页面中使用自定义导航栏 page.wxml 这样一来，你就可以在自定义导航栏中处理各种点击事件，完全掌控其行为和样式。此外，自定义导航栏组件可以反复使用，还能根据需要灵活调整。

学习小红书
type: item
date: 2024-07-09T20:17:00+08:00
description: 先是介绍了newrank 新红网站, 可以搜索小红书的一些数据. 和小红书官方的蒲公英类似. 注意不是千帆, 千帆是卖家订单管理. 新红虽然是非官方, 数据刷新肯定不如官方及时, 但是比蒲公英的数据肯定更全面的. 蒲公英的目的是要推荐商家与博主合作, 并且管理自己与博主合作的笔记, 所以像是笔记版的1688, 包括筛选博主, 筛选笔记,管理合作的笔记. 所以是没有全局的数据的, 比如某一个类别的整体数据表现. 当然单个博主的数据还是挺全面的. 包括其笔记内容和粉丝画像等. 新红和蒲公英对比 数据 新红 蒲公英 大盘数据 有, 种草流量大盘可看到类别下面的商业笔记和种草达人数量, 计算含商量 无 博主筛选,找对标账号 有, 找红人-红人搜索, 按作者类别/ 粉丝数/ 进行筛选.列表中可以看到合作品牌数 有, 在寻找博主-博主广场中, 可以按内容类目/ 粉丝量搜索. 但合作的笔记数需要点入博主详情页, 笔记案例-按笔记类型-合作笔记中查看, 也可以看近期传播表现-近90日查看笔记数据 课程内容 这一节说定位和赛道,我认为本质还是降本(成本维度)增效(变现维度),另外看自身能力(能不能做)和优势(做的比别人好). 除了上面的优势外, 还有所谓养成号,如挑战减肥多少斤第N天. 赛道: 主题 . 三类赛道: 观点: 心理学,情感等,输出价值观 类目: 类似电商类目的选择 人设: 经营自己,相对较难 变现: 广告/咨询/社区/群聊 评估广告变现能力: 不同赛道的含商量, 大牌不太在乎变现, 可能只想种草. 对应一个垂类市场变现能力就强 定义含商量: 商业笔记数量/种草达人数量 种草大盘 如 影视综: 6345/63110 = 0.1商业笔记(报备)/种草达人. 科技互联网 0.03, 美妆: 0.3 健康养生:0.4 职场: 0.01 旅游: 0.05 家居家装: 0.1 运动健身: 0.08 摄影摄像: 0.01 情感星座: 0.1 科学科普: 0.04 母婴 17w/79w=0.23 美食: 0.05 生活: 0.08 交通工具 <0.01 教育 0.03 小博主主要走非报备. 报备:非报备=1:1 对标账号的变现能力分析 举例账号: 内在小孩关爱计划 teacher账号 阿言roy(地方的MCN) 挪威Talk 其他 魏知新(No1 麻瓜MCN) 搭建人设 个人优势转化为他人价值(1. 利他; 2. 观点引发共鸣) 个人简介: 1. 介绍成就; 2. 经历; 3. 账号主要内容; 4. 联系人/Slogan 小红书主页经营: 头像/背景/介绍/打卡瞬间/封面 (这些都是告知算法自己是什么账号) 深耕.不单单是重复,还要做深. 商家倾向于投中小博主(1~5W) 红人搜索:作者类别 维系微信和小红书群。小红书群用于转发点赞，微信群用于聊天。 图文还是视频？答：从图文转视频。 知识类成本<非知识类的成本 单一场景<多场景 xx 100个系列 数码赛道抽奖比较容易提升点赞 标题反复强调相同的点，形成强化 呈现形式带植入点（产品植入）就容易变现广告 利用社会资源降低成本 要判断选题吸引观众的原因：是标题文字还是封面图片？ 笔记分为两种：冲流量和粉丝的笔记（未来隐藏）和长期呈现的 笔记要写得扎心 观众为什么要点进来形成流量？奔着热点话题. 一开始不要打造差异化，先形成足够的用户（做好模仿），再去差异，筛选出用户。 小红书选题策略 流量选题 人设选题 商业选题 选题需要挖掘而不是去凭空想 自动化：在发现页找选题：点赞高的题目->搜索->看其中有多少点赞高的->看点赞高的作者粉丝数是否低->给出评分。最后要排除封面太好看点进来的。 点赞高有三个原因：1选题好，2粉丝多，3封面靓。要去排除2和3，找到仅因为选题好而获赞的选题。(粉丝少但流量高） 新鲜度：区分是最近的流行爆款（一个月内）还是长期的爆款（年年有） 建立选题库 通过tag寻找。点击tag->筛选->最热->回到上面的路径，找低粉高赞的选题。 通过笔记灵感寻找。小红书“创作服务平台“->笔记灵感->最热。有点接近于笔记灵感 同样的选题反复讲。 看到还有个区别是内容更加真诚更容易吸引人。 新红查找法（付费的）。新红中按互动量排名搜索。 还可以按爆款笔记排行榜查。 火过的选题还会再火，过段时间再次做。

C语言Struct+Flash实现类似JSON配置文件的方式
type: item
date: 2024-07-09T11:04:25+08:00
description: JS中存储JSON只要简单的将object stringify以后写入文件就可以. 反过来读取就是读入文件为字符串再parse. C语言如何实现配置文件呢? struct当然是最像json的了, 保存就用Flash. 这儿需要注意struct和flash的麻烦之处. struct的成员变量无论是什么类型,都需要内存地址对齐. struct变量所占内存是连续的, 且大小可以整除最大的变量类型大小. 比如 struct{char a; long b;}x; 那么sizeof(x)不是1+8=9,而是16. 这样如果flash寸土寸金就会显得浪费, 此时可以都用char存储. 这样存储时为了提高内存访问效率, 可以看这篇文章的解析, 有图示. 另外,struct类型的变量名不是地址, 如上面的x,要访问这个变量的地址需要加&,如&x. 这和数组就很不一样. 数组的变量名就是数组的地址. struct变量名其实更像普通变量. flash 在前面讲过了, 每次写入需要擦除, 擦除需要整个扇区. 简单的做法, 就是把struct转为空指针, 并按大小存储到flash中. 读取也是同样.