欢迎你来看我的博客
- 如果有帮到你一点点
- 给我一个 ✨ 好不好 Github
欢迎你来看我的博客
前言 AutoX.js 使用的是 Rhino 作为 JavaScript 引擎,并不支持完整的 nodejs 模块,所以没法直接调用 nodejs 下的 OSS 包。 下面展示使用 OSS Android SDK 完成上传的过程 准备工作 前往 OSS Android SDK,下载依赖包 将 aar 格式的 SDK 转换为 dex 这里使用 Android Studio 提供的工具 d8,进入到 Android Studio 安装目录下,d8 一般在 build-tools 下,MacOS 下为 ~/Library/Android/sdk/build-tools/{version}/ ./d8 --release --output output_folder oss-android-sdk-2.9.13.aar 会生成一个 classes.dex 的文件 拷贝 classes.dex 到手机 截图 // 安卓版本高于 Android 9,需要手动确认授权 if (device.sdkInt > 28) { // 等待截屏权限申请并同意 threads.start(function () { // 这里的系统提示框可能不是运行,改成对应文本即可 packageName("com....
安装 chrome 1, 使用 wget 命令下载最新的 Chrome 64 位 rpm 软件包 wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm 2, 安装 rpm 包 sudo dnf localinstall google-chrome-stable_current_x86_64.rpm 安装 microsoft edge 1, 下载并导入 microsoft 的 GPG 公钥 sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc 2, 添加程序安装源 sudo dnf config-manager --add-repo https://packages.microsoft.com/yumrepos/edge 3, 修正安装源的文件名称 sudo mv /etc/yum.repos.d/packages.microsoft.com_yumrepos_edge.repo /etc/yum.repos.d/microsoft-edge-stable.repo 4, 安装 sudo dnf install microsoft-edge-stable 更新 chrome sudo dnf update google-chrome-stable 卸载 chrome sudo dnf remove google-chrome-stable 可能遇到的问题 打开浏览器失败 由于我是在没有图形界面的系统上运行 chrome,系统缺少 X 服务器 需要在启动 chrome 时,添加参数 --no-sandbox...
在使用 js 的库 xlsx 解析 Excel 表格数据的时候,其中一个日期字段,解析之后是 45040.3964930556 这样子,在 Excel 中展示的是 2023/4/24 9:30 这又是什么奇怪的格式,看起来也不像时间戳啊 oa date (OLE Automation date) oa date 使用浮点数来保存时间,分为两个部分,整数部分从 1899年12月30日 以来的天数,小数部分是这一天的时间除以24 js 中的 Date 对象则是从 自 1970年1月1日 起经过的毫秒数 如何转换 1. 使用 moment.js 库 moment 提供了一个插件 moment-msdate,参考文档 把 moment 对象转换为 oa date moment().toOADate(); // 一个浮点数 把 oa date 转换为 moment 对象 moment.fromOADate(41493); // Wed Aug 07 2013 00:00:00 GMT-0600 (MDT) 2. 自定义函数 把 Date 对象转换为 oa date function JSDateToOADate(date: Date) { return (date....
为了获取生产环境报错对应的源码位置,之前将打包之后的 map 文件上传到 node 服务,日积月累之下,已经占用了好几个 g 的磁盘空间 就想到用 LRU 算法 的思想去对这些文件进行管理 LRU LRU 英文全称是 Least Recently Used,最不经常使用,是一种内存管理算法。可以参考 leetcode 的描述 LRU缓存机制 核心思想是 “如果数据最近被访问过,那么将来被访问的几率也更高”。所以在容量有限的情况下,淘汰最近最少使用的缓存。即近期内最不会被访问的数据进行淘汰 可以使用一个队列来缓存数据 如果有新数据插入,就移出队列中最后一个缓存 如果有数据访问,要将访问到的数据移到尾部,重新进行排序 实现 在 javascript 中,可以使用 Map 或者 Set 来模拟一个队列 import path from "path"; import fse from "fs-extra"; /** 上传 sourcemap 存放地址 */ export const sourcemapFilePath = path.join(__dirname, "../../../../uploads"); // 使用 LRU 算法去控制 sourcemap 文件 export class SourcemapCache { private path = path.join(__dirname, "cache.json"); private length: number; // 最大缓存数量 private cache: Set<string>; constructor(length = 10) { this....
const obj = { foo: { bar: { foo: { bar: 'https://findmio.github.io/post/skills/在nodejs中深度打印对象/', foo: undefined } } } }; 如何在 nodejs 中打印这样一个对象? 直接使用 console.log 会有什么问题 { foo: { bar: { foo: [Object] } } } 对象的嵌套层级超过三层,就会显示为 Object 那么该如何完整的打印出这个对象呢? 方法一:JSON.stringify() 众所周知,此方法是将 JavaScript 对象或值转换为 JSON 字符串,直接调用的返回值可读性不是很好 console.log(JSON.stringify(obj)); 可以使用 第三个参数 space (缩进用的空白字符串,如果为数字,则代表有多少个空格),来进行美化 console.log(JSON.stringify(obj, null, 2)); 缺点: 没有对输出结果的值高亮 JSON.stringify() 会对一些属性进行处理,比如忽略掉 undefined 、函数以及 symbol 值 方法二:console.dir() 和 util.inspect 这两个函数的参数是一样的,比较常用的有,查看完整参数 showHidden :如果为 true,则格式化结果中会显示隐藏的不可枚举的符号和属性。默认为 false depth:格式化对象时进行递归的次数,如果要使其无限递归,可传入 null 或者 Infinity。默认为 2 colors:如果为 true,输出带 ANSI 颜色的代码。默认为 false // 需要导入 nodejs 核心模块 util console....
题目 地址:https://leetcode.cn/problems/two-sum/ 思路 通过 Map 把数组的每一项进行缓存 (key 为数组中的项,value 为索引),然后再对数组进行遍历,并计算是否存在 key 相加等于目标值 遍历数组,判断差值是否存在 Map 中 如果存在,返回对应的索引 如果不存在,将这一项添加到 Map 中 数组遍历结束,返回一个兜底的数组 [-1, -1] /** * @param {number[]} nums * @param {number} target * @return {number[]} */ var twoSum = function (nums, target) { const map = new Map(); for (let i = 0; i < nums.length; i++) { const item = nums[i]; const different = target - item; if (map.get(different) !== undefined) { return [map....
树 树 是数据结构中很常见的一种数据结构,是一种分层数据的抽象模型。 树形结构存在下列特征: 除根节点外,每个节点都有一个父节点 每个节点有零个或者多个子节点 二叉树 二叉树 是树形结构中的一种。 二叉树中的节点最多只能有两个子节点:一个是左节点,一个是右节点。 二叉搜索树(BST)是二叉树的一种,但是只允许你在左节点存储(比父节点)小的值, 在右节点存储(比父节点)大的值。 实现一个二叉搜索树 构造一个节点的类用来存储节点值和左右节点 构造一个二叉搜索树的类,它有一个根节点 实现插入节点的方法(insert) 根据插入的值创建一个节点 判断是否存在根节点 不存在根节点:直接将根节点指向此节点 存在根节点:将根节点和此节点传入 insertNode 方法去处理插入的位置 实现判断插入节点位置的方法(insertNode)。第一个参数为父节点,第二个参数为子节点 判断子节点要插入到父节点的左侧还是右侧:比父节点小的插入到父节点左侧,比父节点大的插入到父节点右侧 找到子节点要插入到父节点的位置,判断该位置是否已存在 如果被插入的位置已存在的,则递归调用 insertNode 方法,将父节点替换为被插入位置的节点 如果被插入的位置不存在的,直接将子节点插入到父节点上 class Node { // {1} constructor(value) { this.val = value; // 节点值 this.left = null; // 左节点 this.right = null; // 右节点 } } class BinarySearchTree { // {2} constructor() { this.root = null; // 根节点 } insert(value) { const node = new Node(value); // {3} if (this....
题目 实现一个 LazyMan,可以按照以下方式调用: LazyMan('Tony'); // Hi I am Tony LazyMan('Tony').sleep(10).eat('lunch'); // Hi I am Tony // 等待了10秒... // I am eating lunch LazyMan('Tony').eat('lunch').sleep(10).eat('dinner'); // Hi I am Tony // I am eating lunch // 等待了10秒... // I am eating diner LazyMan('Tony') .eat('lunch') .eat('dinner') .sleepFirst(5) .sleep(10) .eat('junk food'); // Hi I am Tony // 等待了5秒... // I am eating lunch // I am eating dinner // 等待了10秒... // I am eating junk food 思路 总共需要实现三个函数:一个同步的 eat,两个异步的 sleep、sleepFirst。...
题目 地址:https://leetcode.cn/problems/fibonacci-number/ 解题 斐波那契数列的特点是由后两个数字相加得出下一个数字, 首先能想到的就是用递归来解决。 递归的出口是 F(0) = 0,F(1) = 1 找到出口之后就很简单了,三下五除二就写出来: var fib = function (n) { if (n <= 1) { return n; } function add(num) { if (num === 1 || num === 0) { return num; } else { return add(num - 1) + add(num - 2); } } return add(n); }; 愉快的提交之后, 嚯,击败了 14% 的提交。 优化 由于盲目的使用递归,造成了大量的重复操作,时间复杂度是 O(2^n),指数级爆炸。 自顶而下 为了解决这些重复的操作,使用 memoization 的思想来对已计算的数据进行缓存。 下面来用 数组 实现一下:...