git无法签出代码

Q: 在Windows10上使用git clone代码的时候抛出了异常,重试了几次都是相同的错误:下载的目录里除了.git没有任何东西。 A: 源代码是在linux上编写的,但是在Windows10上拉取代码却出现了问题。根据提示可以看出代码clone是成功的,但是checkout的时候出现了错误。那么问题很可能是不通系统下文件属性或策略导致的。 然后在Git文档上找到一个关于NTFS保护机制的配置,core.protectNTFS: If set to true, do not allow checkout of paths that would cause problems with the NTFS filesystem, e.g. conflict with 8.3 “short” names. Defaults to true on Windows, and false elsewhere. Windows系统下默认值是true,也就是说不符合NTFS策略的文件不会被签出,设置为false后可以关闭保护机制。 git config core.protectNTFS false

2025年7月21日 · 1 分钟 · 43 字

sqlite删除记录后数据库文件大小不变

最的做的项目中要有到sqlite数据存储,写了测试程序进行测试,存入300万条记录,占用flash大小为 86.1M,当把表中的记录全部删除后发后数据库文件大小依然是 86.1M; 原因是: sqlite采用的是变长纪录存储,当你从Sqlite删除数据后,未使用的磁盘空间被添加到一个内在的”空闲列表”中用于存储你下次插入的数据,用于提高效率,磁盘空间并没有丢失,但也不向操作系统返回磁盘空间,这就导致删除数据乃至清空整个数据库后,数据文件大小还是没有任何变化,还是很大 解决方法:两种 在数据删除后,手动执行VACUUM命令,执行方式很简单 sqlite> vacuum; VACUUM命令会清空“空闲列表”,把数据库尺寸压缩到最小。但是要耗费一些时间。 FQA里面说,在Linux的环境下,大约0.5秒/M。并且要使用两倍于数据库文件的空间。 我憎恨此FQA,他只说系统环境,不说机器硬件环境。我在测试手机上执行用了将近13秒时间压缩了将近3M的空间。至于它所占用的另一部分空间,是生成了一个.db-journal后缀名的临时文件。(这个问题对我现在来说是无所谓的。) 在数据库文件建成中,将auto_vacuum设置成“1” 注意:只有在数据库中未建任何表时才能改变auto-vacuum标记。试图在已有表的情况下修改不会导致报错。 cmd.CommandText = “PRAGMA auto_vacuum = 1;” cmd.ExecuteNonQuery() 当开启auto-vacuum,当提交一个从数据库中删除除数据的事物时,数据库文件自动收缩。 数据库会在内部存储一些信息以便支持这一功能,这使得数据库文件比不开启该选项时稍微大一些。 我的表结构,不含任何数据是,数据库文件大小是25K左右,开了auto_vacuum之后是26K。 插入运行基础数据后,文件变成35K,开了auto_vacuum之后是36K。 变化不大,无所谓。 但是第二个方法同样有缺点,只会从数据库文件中截断空闲列表中的页, 而不会回收数据库中的碎片,也不会像VACUUM 命令那样重新整理数据库内容。实际上,由于需要在数据库文件中移动页, auto-vacuum 会产生更多的碎片。而且,在执行删除操作的时候,也有那个.db-journal文件产生。 要使用auto-vacuum,需要一些前题条件。 数据库中需要存储一些额外的信息以记录它所跟踪的每个数据库页都找回其指针位置。 所以,auto-vacumm 必须在建表之前就开启。在一个表创建之后, 就不能再开启或关闭 auto-vacumm。 其实按照运行时间上的比较,两个在做了大删除操作后,从3M变到35K的时间其实差不多,执行VACUUM命令稍微长一点,但是也长不了多少,相对而言,这种一点点的长可以忽略不计。 加上AUTO的方式对碎片的造成情况,如果数据交换次数多的话,这种方式很不合适。

2025年7月19日 · 1 分钟 · 39 字

sqlite获取插入id的几种方式

SQLite 中,表设置自增列后,可通过如下几种方式获取插入记录的 ID sqlite_sequence insert into TbTest(Name, Age) values('usr', 20); select seq from sqlite_sequence where name='TbTest'; rowid --表设置了自增列,会生成 rowid 的隐藏列,需要显式查询语句才可以查询出 select rowid from TbTest; --但是,表没有设置自增列,上面的语句无法查出任何值 --特殊的,表无论是否设置了自增列,但都可以使用聚合函数查询出 rowid insert into TbTest(Name, Age) values('usr', 20); select max(rowid) from TbTest; ID列 insert into TbTest(Name, Age) values('usr', 20); select max(ID) from TbTest; last_insert_rowid insert into TbTest(Name, Age) values('usr', 20); --注意!若此行处有插入临时表的操作,下面的语句获取到的是插入临时表的 rowid select last_insert_rowid() from TbTest LIMIT 1;

2025年7月19日 · 1 分钟 · 63 字

ComputeStringHash错误解决办法

用 ILSPY 或者 .NET Reflector 、dnspy 等反编译出来之后 文件由于语法不符合已经被丢弃了, 所以在反编译工具里面找到这个类,手动复制出来,新建一个类,把尖括号等去掉,方法就只保留 ComputeStringHash 方法就行了。 再在报错的地方也把尖括号去掉。 这个方法原本是一个string类型的switch,switch本身就要计算hash来判断,但是反编译工具对这个的解析出了问题, [CompilerGenerated] internal sealed class PrivateImplementationDetails { internal static uint ComputeStringHash(string s) { uint num = 0; if(s != null) { num = 2166136261U; for(int i=0;i<s.Length;i++) { num = ((uint)s[i] ^ num)*16777619U; } } return num; } } 重建类后测试 ComputeStringHash(“link”)最后的结果就是 232457833 , 如果判断条件不多的话其实可以直接把这个数字判断全部删掉,重写switch或者if都可以。如果判断条件很多懒得弄就自建PrivateImplementationDetails是最简单的

2025年7月19日 · 1 分钟 · 55 字

无依赖的LitJSON

将JSON映射到对象,反之亦然 为了在内部使用JSON格式的数据。网络程序,自然 我想到的方法是使用JSON文本填充新实例 属于某一特定类别;要么是定制的,与结构相匹配 输入JSON文本或充当字典的更通用的文本。 相反地为了从存储在对象中的数据构建新的JSON字符串, 一个简单的export-like操作听起来是个好主意。 为此,LitJSON包括JsonMapper类, 它提供了两种主要的方法来处理JSON-to-object和 对象到JSON转换。这些方法是 JsonMapper.ToObject和JsonMapper.ToJson。 简单的JsonMapper示例 如下例所示,ToObject方法具有泛型 变体JsonMapper.ToObject<T>,用于指定 待归还的物品。 using LitJson; using System; public class Person { // C# 3.0 auto-implemented properties public string Name { get; set; } public int Age { get; set; } public DateTime Birthday { get; set; } } public class JsonSample { public static void Main() { PersonToJson(); JsonToPerson(); } public static void PersonToJson() { Person bill = new Person(); bill.Name = "William Shakespeare"; bill.Age = 51; bill.Birthday = new DateTime(1564, 4, 26); string json_bill = JsonMapper.ToJson(bill); Console.WriteLine(json_bill); } public static void JsonToPerson() { string json = @" { ""Name"" : ""Thomas More"", ""Age"" : 57, ""Birthday"" : ""02/07/1478 00:00:00"" }"; Person thomas = JsonMapper.ToObject<Person>(json); Console.WriteLine("Thomas' age: {0}", thomas.Age); } } 示例输出: ...

2025年7月19日 · 5 分钟 · 909 字

windows守护进程工具nssm

nssm简介 nssm是一个服务封装程序,它可以将普通exe程序封装成服务,实现开机自启动,同类型的工具还有微软自己的srvany,不过nssm更加简单易用,并且功能强大。 它的特点如下: 支持普通exe程序(控制台程序或者带界面的Windows程序都可以) 安装简单,修改方便 可以自动守护封装了的服务,程序挂掉了后可以自动重启 官网地址:https://nssm.cc/ nssm配置详解 下载地址 官网地址:https://nssm.cc/download 解压压缩包,根据系统位数选择64或32位程序 打开命令行,运行nssm程序 管理员权限打开命令行工具,切换到nssm.exe所在路径,运行 nssm install,打开程序配置界面 配置项说明: Path:运行应用程序的程序 Startup directory:应用程序所在的目录 Arguments:应用运行的参数 Service name:生成服务的名称 最后点击install service 完成windows服务安装,在windows服务列表就能看到创建的服务了。 常用命令 nssm install servername //创建servername服务,弹出配置界面 nssm start servername //启动服务 nssm stop servername //暂停服务 nssm restart servername //重新启动服务 nssm remove servername //删除创建的servername服务 nssm edit servername//更改servername服务,弹出修改界面 nssm set servername 参数名 参数值 //设置服务参数值 sc delete servername//windows删除服务命令 直接使用windows的服务管理也可以实现服务的操作,服务右键属性 - 恢复即可设置服务挂掉重启等内容。 实战:将应用做成服务 程序说明 这里演示将net6的web项目制作成windows服务 应用的启动命令是: dotnet WebApplication_nssm.dll --urls=http://*:8888/ --port=8888 安装服务 nssm install Path:C:\Program Files\dotnet\dotnet.exe Startup directory:D:\TechLearn\001、Tools--nssm\WebApplication_nssm\bin\Debug\net6.0 Arguments:WebApplication_nssm.dll --urls=http://*:8888/ --port=8888 Service name:webapp8888 最后点击install service 完成windows服务安装,在windows服务列表就能看到创建的服务了。 管理服务 启动服务 D:\nssm-2.24\win64>nssm start webapp8888 webapp8888: START: 操作成功完成。 关闭服务 D:\nssm-2.24\win64>nssm stop webapp8888 webapp8888: STOP: 操作成功完成。 重启服务 如果服务未启动就会直接启动,启动的会重启。 D:\nssm-2.24\win64>nssm restart webapp8888 webapp8888: STOP: 服务尚未启动。 webapp8888: START: 操作成功完成。 D:\nssm-2.24\win64>nssm restart webapp8888 webapp8888: STOP: 操作成功完成。 webapp8888: START: 操作成功完成。 修改服务 输入命令,修改配置,不能修改服务名 ...

2025年7月17日 · 1 分钟 · 134 字

nvm安装配置教程

nvm 简介 nvm 全称为 node.js version management,顾名思义是用于管理多个 nodejs 的版本控制工具。通过 nvm 可以安装和切换不同版本的 nodejs。nvm 主要是为了解决 node.js 各种版本存在不兼容现象。 nvm 的安装与配置 网上搜索…

2025年7月15日 · 1 分钟 · 18 字

Hello World

我觉得程序员这个群体是非常幸运的一群人,我们生在一个技术改变世界的时代,而我们可能正做着能够改变世界的技术,这是何等的荣耀和机遇。 ——《MacTalk 人生元编程》 前言 大概每个程序员在开篇都会写一个 Hello World! 来作为开始。这是我的第一篇博客,就来写一写程序员眼中的 Hello World!。 这是一个 01 的世界 每个伟大的梦想都来自最小的尝试。秒写一个代码:hello.c #include <stdio.h> int main() { printf("Hello world\n"); return 0; } 这段代码相信大家都很熟悉,无非就是输出一个 Hello world 字符串。下面我们就来分析一下这段代码。 预处理阶段 我们可以使用 gcc -E hello.c -o hello.i 来将预处理之后的数据存到 hello.i 中,或者使用 > 重定向到指定的文件,预处理的结果比较简单,大家可以直接看输出的结果。 编译阶段 gcc -S hello.i -o hello.s 将预处理之后的文件编译成 hello.s 文件。 在编译阶段,编译器检查代码的规范性、是否有语法错误等,在检查无误后,gcc 把代码翻译成汇编语言。 我们来看一下编译之后的文件 >more hello.s .file "hello.c" .section .rodata .LC0: .string "Hello world" .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $.LC0, %edi call puts movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2" .section .note.GNU-stack,"",@progbits 汇编阶段 汇编阶段将编译阶段生成的.s 文件转成二进制目标代码。 gcc -c hello.s -o hello.o 生成了.o 二进制文件,这时就不能使用 more 来进行文本查看了,可以使用 objdump 命令。 objdump -d hello.o ...

2025年7月15日 · 2 分钟 · 292 字

【加解密】动态令牌-(OTP,HOTP,TOTP)-基本原理

名词解释和基本介绍 OTP 是 One-Time Password的简写,表示一次性密码。 HOTP 是HMAC-based One-Time Password的简写,表示基于HMAC算法加密的一次性密码。 是事件同步,通过某一特定的事件次序及相同的种子值作为输入,通过HASH算法运算出一致的密码。 TOTP 是Time-based One-Time Password的简写,表示基于时间戳算法的一次性密码。 是时间同步,基于客户端的动态口令和动态口令验证服务器的时间比对,一般每60秒产生一个新口令,要求客户端和服务器能够十分精确的保持正确的时钟,客户端和服务端基于时间计算的动态口令才能一致。 原理介绍 OTP基本原理 计算OTP串的公式 OTP(K,C) = Truncate(HMAC-SHA-1(K,C)) 其中, K表示秘钥串; C是一个数字,表示随机数; HMAC-SHA-1表示使用SHA-1做HMAC; Truncate是一个函数,就是怎么截取加密后的串,并取加密后串的哪些字段组成一个数字。 对HMAC-SHA-1方式加密来说,Truncate实现如下。 HMAC-SHA-1加密后的长度得到一个20字节的密串; 取这个20字节的密串的最后一个字节,取这字节的低4位,作为截取加密串的下标偏移量; 按照下标偏移量开始,获取4个字节,按照大端方式组成一个整数; 截取这个整数的后6位或者8位转成字符串返回。 Java代码实现 public static String generateOTP(String K, String C, String returnDigits, String crypto){ int codeDigits = Integer.decode(returnDigits).intValue(); String result = null; // K是密码 // C是产生的随机数 // crypto是加密算法 HMAC-SHA-1 byte[] hash = hmac_sha(crypto, K, C); // hash为20字节的字符串 // put selected bytes into result int // 获取hash最后一个字节的低4位,作为选择结果的开始下标偏移 int offset = hash[hash.length - 1] & 0xf; // 获取4个字节组成一个整数,其中第一个字节最高位为符号位,不获取,使用0x7f int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff); // 获取这个整数的后6位(可以根据需要取后8位) int otp = binary % 1000000; // 将数字转成字符串,不够6位前面补0 result = Integer.toString(otp); while (result.length() < codeDigits) { result = "0" + result; } return result; } 返回的结果就是看到一个数字的动态密码。 ...

2025年7月11日 · 3 分钟 · 450 字