- 博客(80)
- 收藏
- 关注
原创 通用数据库对象设计
这里的数据模型以陈品山的实体-关系模型为基础,增加了两点修改。一是用“组”的概念表达实体间关系,并将组作为一种特殊实体。二是采用继承的思想,将实体的公共属性提取出来,放到统一表中。实体的特有属性保存在单独的表中。根据这两点,我们建立一个实体表,记录全部实体的公共属性。为了跟踪实体的变化,需要为实体分配唯一标识。为了支持分布式应用,索引不能使用数据库自增字段。而唯一标识是OLTP业务检索时最常用的索引,需要支持高性能查询。
2024-10-16 11:25:22 1055
原创 回到原点再出发
本文总结了近35年来的数据模型方案,分成9个不同的时代,讨论了每个时代的方案。我们指出,基础的数据模型思想只有少数的几个,大多已经出现很长时间了。新方案难免相似于旧模型。研究以前的方案,是很有价值的练习。此外,我们介绍了在分析每个时代数据模型时获得的经验。当代研究人员往往没有经历过以前的年代,缺乏(如果有)对前人经验的理解。古话说:不知史,蹈覆辙。通过介绍历史经验,我们希望将来的研究人员可以避免重复历史。很不幸,当前XML时代的方案和1970年代的CODASYL模型相似,后者因为过度复杂遭受失败。
2024-10-08 23:08:37 1149
原创 只崩溃软件
只崩溃程序可以安全崩溃迅速恢复。只有一种方法可以停止这类软件:让它崩溃。同样也只有一种方法可以启动软件:执行恢复。只崩溃系统使用只崩溃组件构建,使用组件级自动重试,避免内部组件崩溃影响终端用户。在本文中我们建议对互联网系统采用只崩溃设计,证明了只崩溃设计能够产生可靠的代码、简单的故障预防和快速高效的故障恢复。我们介绍了关于建立只崩溃互联网服务的思路,将成功技术发挥到极致。
2024-08-10 19:33:42 800
原创 复杂系统失效原理
基于“根源”的分析和结论反映的不是在技术层面上对故障性质的认知,而是将后果归咎于特定原因或事件的社会和文化需求。灾难的发生,往往是由于多个不起眼的小问题同时出现,构成触发系统性故障的条件。故障最初的征候大部分被系统的安全措施屏蔽了,传递到运维层面的征候也往往没有被一线人员汇报。事后一线人员的行为可能被看作是错误或违规,这种评价存在严重的事后偏见,忽视了其他方面的驱动因素,特别是生产目标压力。事后看来,故障往往是不可避免的,一线人员的行为则是过错或对事故征兆的无视。系统的安全状态是动态的。
2024-07-01 19:42:27 929
翻译 质感设计-样式-字体排印Typography
如果需要支持不同尺寸的设备,可以定义字体等级,添加或移除样式,甚至使用其他字体替换Roboto。质感设计采用以14号为基准尺寸的大二度字体等级。基准尺寸是排版正文最常用的样式。图9 质感设计字体等级采用大二度比例(1.125)。字体等级渲染尺寸应当以产生显著区别为目标,避免细微差异。图10 质感设计字体等级包含15种样式。图11 你的产品大概不会使用质感设计字体等级中全部的样式。在本例中,我们选择五种字体尺寸,忽略其他样式。图12 如果质感设计字体等级无法满足需求,你可以修改相应数值。
2024-03-18 22:38:19 192
原创 使用CompositionLocal简化组合式函数参数
为了解决这个问题,Jetpack通过CompositionLocal提供了一个带有层级结构的状态树,可以理解为OOP中把继承树中所有对象的行为移除之后的结果。从上面的例子可以看到,通过CompositionLocal可以隐式传递对象,并且传递给组合式函数对象可以由父函数控制,限制在特定范围内。因为我们可以把哪些与组合式函数自身逻辑无关,同时又会影响函数结果的对象放到CompositionLocal中,简化函数参数列表。代码4 部分内置的CompositionLocal对象。Text("打开屏幕2")
2024-03-08 14:54:07 628
原创 对实现移动应用界面设计的思考
内容的来源通常有3个部分:本地数据(包括数据库、媒体文件、偏好设置等)、远程数据(比如发送HTTP请求获得的数据)、用户输入的数据。这里有一个问题,两部分内容不是平等或独立的,用户输入的数据可能影响后端数据流,二者更像是流水线上前后两个步骤的关系:用户输入流的变化会改变后端数据流。内容是静态的,可以封装成被动对象(见《架构蓝图:软件架构4+1视图模型》的“视图之间的联系”部分)作为参数传递给组合式函数。随着用户输入数据的变化,以及用户发出新的操作指令,内容会发生变化,或者说会产生新版本。
2024-02-24 18:02:48 989 1
原创 Android开发中“真正”的仓库模式
Figure 1: 仓库模式多年来我见过很多仓库模式的实现,我想其中大部分是错误而无益的。下面是我所见最多的5个错误(一些甚至出现在那么要如何把仓库模式做对呢?
2024-01-03 23:40:58 906
原创 使用Jetpack Compose加载数据的一个常见错误(Compose死循环)
下面的数据类用于从firestore数据库加载数据。如果使用flow加载数据,必须确保获取数据的动作仅仅执行一次。如果使用了函数,compose将进入死循环(时间戳将不断持续更新)。如果需要使用函数,必须在LaunchedEffect中调用函数。Created: 2023-11-10 周五 23:10。Date: 2023年11月10日。添加时间戳来检查数据加载次数。
2023-11-10 23:13:37 282
原创 质感设计-样式-色彩
质感设计采用HCT色彩空间。HCT表示色相(Hue)、饱和度(Chroma)和色调(Tone)。质感设计通过调整关键色彩的色调生成不同职能的色彩。色调描述色彩的亮度,0是最暗的黑色,100是最亮的白色。比如tertiary40表示将第三关键色彩的色调设定为40而产生的色彩。除此以外,质感设计提供了警示色彩(error color)。质感设计以5种关键色彩为基础,衍生出20余种色彩职能。表层色彩(Surface color)用于将一个区域与屏幕背景或其他区域隔离。每种显著色彩可以衍生出4种色彩职能。
2023-08-23 00:00:30 301
原创 架构蓝图:软件架构4+1视图模型
本文提出的模型可以描述由多个软件所组成的系统的架构。该模型同时使用多个视图。这些视图可以分别展示系统架构的不同利益相关方(终端用户、开发者、系统工程师、项目经理等)的关注点,以及分别处理功能和非功能需求。文本介绍了全部的五个视图,并使用符号进行表达。视图的设计使用了以架构为中心的、场景驱动的迭代开发过程。关键字:软件架构、视图、面向对象设计、软件开发过程我们见过很多书和文章尝试用一张图来捕捉系统架构的全部要点。仔细看看图里的方框和箭头,显然作者竭力尝试在一张图片上展示超过图片自身表达能力的东西。
2023-08-22 21:43:30 1845
原创 对JUnit 4和安卓测试代码的简单分析
JUnit 4是一种流行的Java单元测试工具。使用JUnit 4和androidx.test包可以为Android程序编写单元测试和插桩测试。下面我对JUnit 4在Android程序上的使用做一些简单的分析。
2023-08-15 11:44:18 280
原创 UiAutomator
为避免此情况,可以调用UiDevice::wait或UiObject::waitForExists方法等待控件渲染完毕。从上面的介绍可以看出,UiDevice和UiObject是两个核心类,UiDevice可以对设备进行操作,UiObject可以对控件进行操作。通过UiDevice你可以按下主页键、返回键,可以打开应用、选择界面上具有某个属性的控件等。UiDevice提供了方法findObject(uiSelector: UiSelector):UiObject来获取界面上的某个控件。
2023-07-28 21:48:56 414
原创 OAID学习
为了在包含用户隐私的同时,让广告商可以了解用户在应用中的行为,安卓系统提供了OAID(Open Anonymous Device Identifier)用来跟踪设备。OAID是一种非永久的、近似唯一的设备标识符,由字母和数字组成,长度不超过64位。虽然IMEI不包含用户的个人信息,但在设备被盗或维修时,第三方可以通过IMEI确认设备身份和行踪,获取用户隐私。IDFA是自动生成的,生成算法保密。除上述情况外,OAID通常是不变的,可以用来跟踪设备。OAID采用随机算法生成,不同设备的OAID大概率是不同的。
2023-07-28 14:40:42 6403
原创 从SpringBoot迁移到Quarkus
近期将一个小程序从Spring boot迁移到了Quarkus。之所以决定进行迁移,一是想尝试一些新的Java语法和框架;二是程序比较小,迁移成本低。选择Quarkus的原因也有两点:一是对native image的支持较好。二是对Java标准的支持较好。因为我的程序规模较小,加上我希望程序能更贴近标准,减少对特定API的依赖,因此我没有使用这些插件。Quarkus有一些扩展可以简化迁移工作,这些扩展可以在。
2023-05-08 22:58:15 1161
原创 Android访问系统下载目录
共享媒体文件也包括系统下载目录中的文件。MediaStore以ContentProvider的方式提供了文件信息,得到文件信息后,可以直接打开文件访问数据。MediaStore.MediaColumns.DATA列是文件的全名。有了全名,就可以使用File和InputStream可以访问文件中的数据。// 方法二:使用ContentResolver。Listing 1: 读取下载目录下的文件信息。Listing 2: 访问文件中的数据。// 方法一:使用File对象。Listing 3: 新建文件。
2023-05-06 11:11:30 1663
原创 Material3设计指南笔记
强调色用于突出显示某些界面元素。强调色包括一级色primary color、二级色secondary color和三级色tertiary color。比如一级色就包含Primary、OnPrimary、PrimaryContainer、OnPrimaryContainer4个颜色。Material3将界面中的颜色分为强调色accent color、中性色neutral color和辅助色additional color三类。强调色用于突出显示某些界面元素,中性色用作背景颜色,辅助色用于展示错误信息。
2023-03-05 14:02:07 2228
原创 使用扩展事件记录 SQL 执行历史
http://tommwq.tech/blog/%e4%bd%bf%e7%94%a8%e6%89%a9%e5%b1%95%e4%ba%8b%e4%bb%b6%e8%ae%b0%e5%bd%95-sql-%e6%89%a7%e8%a1%8c%e5%8e%86%e5%8f%b2/扩展事件(XEvent)是 SQL Server 从 2008 版本开始提供的一种记录系统运行事件的机制。使用扩展事件可以了解 SQL Server 的内部执行情况,其中就包括了执行过哪些 SQL 语句。要记录和查看 SQL..
2022-01-20 17:46:37 667
原创 Jetpack Compose 和即将退场的 Fragment
Jetpack Compose 和即将退场的 Fragment1. 文章信息 2. 介绍 3. 谁杀死了 Fragment? 4. 可组合函数应当放到哪里? 5. 结论1文章信息原文:https://sonique6784.medium.com/jetpack-compose-and-the-fall-of-fragments-54bf9977da1a 作者:Cédric F 翻译:tommwq2介绍本文是关于如何组织 Jetpack Compose 项目结构的。我不会讲怎样..
2021-08-29 00:23:31 3583
原创 git笔记
git笔记git笔记 – tommwq.tech/blog1git简介git是一个分布式版本管理系统。版本管理系统用于记录文件的变化历史。git和其他版本管理工具的区别主要有两点。首先git不会记录文件变更了什么(比如:删除第2行),而是记录文件变更后的快照。其次git是分布式的。git会下载文件的全部历史到本地,因此无需联网也可以正常工作。2获取帮助使用命令git help、git <verb> --help或git help <verb>可以获...
2021-07-05 23:12:15 110
原创 使用C语言实现面向对象编程
使用C语言实现面向对象编程使用C语言实现面向对象编程 – tommwq.tech/blog面向对象是一种程序设计方法。面向对象不是某种语法或语言特性,因此使用任何高级语言都可以实现面向对象程序设计。与之相似的,使用面向对象程序语言,也可以做出非面向对象的程序设计。这里简单介绍一种用C语言实现面向对象的方法。面向对象的核心原则是使用对象来组织程序。对象是可以执行某些行为的东西。为了保证行为是正确的,对象需要维护控制行为的一组状态。要避免状态被外部代码破坏,对象必须保护这些状态,这就产生了面向对象的
2021-06-30 00:45:08 3041
原创 Reactor和Proactor模型
Reactor和Proactor模型Reactor和Proactor模型 – tommwq.tech/blogReactor模型处理过程:消息处理器向分配器注册。 分配器等待消息。 消息到来,系统唤醒分配器。分配器将“消息到达”这一事件通知消息处理器。 消息处理器收到事件后,主动读取消息,进行处理。然后将控制返回给分配器。Reactor的特点:消息处理器需要自己读取消息。 消息处理器如果设计不合理,可能延迟后续“消息到达”事件的接收。 消息处理器在读取消息时更灵活,可以充分使用栈
2021-06-03 15:27:18 89
原创 Windows系统调用工作原理
关于WordPress tommwq.tech/blog 自定义 32个插件更新, 翻译更新 00条评论待审 新建 编辑文章 SEO SEO分数:好 搜索 您好,tommwq注销跳至内容TOMMWQ.TECH/BLOG原文标题 How Do Windows NT System Calls REALLY Work? 原文 https://www.codeguru.com/cpp/w-p/system/devicedriverdevelo..
2021-05-29 21:15:22 1376
原创 UDP是如何工作的
UDP是如何工作的原文:https://www.slashroot.in/how-does-udp-work作者:Sarath Pillai原文发表日期:2017年6月1日翻译:tommwq译文:http://tommwq.tech/blog/?p=370IETF(互联网工程任务组)是一个由工程师和计算机科学家组成的社区,他们致力于带来新的互联网技术、标准和规范。RFC文档就是由IETF发布的。RFC通常是为了进行同行评审而编写的正式文档。RFC主要讨论了不同协议的方法及其完整的
2021-05-10 19:02:41 626
原创 ARP是如何工作的
ARP是如何工作的原文:https://www.slashroot.in/how-does-arp-address-resolution-protocol-work作者:Sarath Pillai原文发表日期:2016年10月10日翻译:tommwq译文:http://tommwq.tech/blog/?p=358网络中的两台机器可以相互通信,如果它们知道对方的物理地址。虽然计算机程序使用IP地址来发送和接收消息,但实际的底层通信总是通过物理地址进行的。我们先来了解一下通信如何通
2021-05-07 23:13:55 254
原创 迭代DNS查询和递归DNS查询的区别
迭代DNS查询和递归DNS查询的区别作者:Sarath Pillai日期:2013月1月12日原文:https://www.slashroot.in/difference-between-iterative-and-recursive-dns-query翻译:tommwq译文:http://tommwq.tech/blog/2021/05/06/349DNS是最关键的基础设施,它对所有人都是公开可用的。实际上可以这么说,如果DNS发生故障,足以摧毁万维网。我曾经在文章中阐述了DN
2021-05-06 22:57:58 1397
原创 DNS服务器是如何工作的
DNS服务器是如何工作的原文:https://www.slashroot.in/how-dns-works作者:Sarath Pillai原文发表日期:2012年10月22日翻译:tommwq译文:http://tommwq.tech/blog/?p=3441DNS服务器历史简介大家好!在这篇文章中,我们将讨论互联网世界中最重要、最不可或缺的资源。这个资源我们每个人都会用到,无论我们是否了解它。网络中的每台机器都被一个数字地址所标识。网络中的机器使用这个地址相互通信。如果没.
2021-05-06 22:57:38 261
翻译 如何通过重写hashCode()方法将偏向锁性能提高4倍?
原文:https://srvaroa.github.io/jvm/java/openjdk/biased-locking/2017/01/30/hashCode.html作者:Galo Navarro原文标题:How does the default hashCode() work?原文发表日期:2017年1月30日翻译:tommwq译文:http://tommwq.tech/blog/?p=338对hashCode()的肤浅了解会引发对JVM源代码的深入探索,认识了对象布局、偏.
2021-04-27 20:32:31 515
原创 几种常见的代码复用级别
几种常见的代码复用级别http://tommwq.tech/blog/2021/03/02/331级别1:复制粘帖这个级别的代码复用是通过复制粘帖完成的。需要复用代码时,找到相似的代码复制过来,稍加修改即可完成。这种复用方法看起来简单、快速,但难以应对需求变更。假设一份代码复制到了10处,需求变化时,就要手动修改10个地方。工作量大,还容易产生缺陷。这种代码复用方式灵活性差、健壮性差。当然,如果只有2-3出使用了相同的代码,可以采用这种方式复用。但如果复制次数超过3次,最好采用更高级别的复用方式
2021-03-02 13:52:16 1388
翻译 Android Studio 4.1中的模板插件
Android Studio 4.1中的模板插件来自:http://tommwq.tech/blog/2021/02/28/312原文:https://steewsc.medium.com/template-plugin-for-android-studio-4-1-92dcbc689d39作者:Stevica Trajanovic如果你在开发一个新项目,或者你想将旧项目迁移到新架构,你应该考虑建立一个模板,好省去编写样板代码的工作,把时间用到其他地方。直到最近之前,要建立模板,只需
2021-02-28 14:28:29 1515 2
原创 如何防御CSRF攻击
http://tommwq.tech/blog/2020/12/28/2941会话和cookie会话(session)这一术语通常有两重含义。首先,会话表示客户端和服务器端之间的一系列交互。一次交互可以理解为一次请求-应答过程。在这一系列交互过程中,往往需要保存一些和交互有关的信息(比如登录信息),这些信息有时叫做通讯上下文(context)。会话也可以用来指代通讯上下文。出于安全性和性能的考虑,通讯上下文通常保存在服务器端。为了让服务器可以同时服务多个客户端,区分不同客户端的上下文,服务器为每个.
2020-12-28 01:43:39 892
原创 一种变更存储过程的方法
http://tommwq.tech/blog/2020/12/24/291存储过程难以使用版本管理,更新和回滚较为复杂。可以为存储过程在数据库中建立多个版本,然后封装一个facade存储过程。这样比对变更、更新、回滚等工作将变得更加简单。假设要新建存储过程foo。首先建立一个存储过程foo_20201224,执行具体的操作。然后建立存储过程foo,调用foo_20201224。create procedure foo (a int, b int)begincall foo_202012
2020-12-24 20:55:47 168
原创 如何对待技术债务
http://tommwq.tech/blog/2020/12/23/289现代软件系统都是采用分层式开发和模块式开发,每一层次的程序都是在更低层次模块的基础上构建的。比如Java程序在读写文件的时候,不会直接操作磁盘硬件,而是使用文件相关的类,这些类又调用操作系统提供的API接口。我们在开发的过程中,很少有从底层模块直接开始开发的,大部分时间是在已经存在的模块上进行修改,在历史代码的基础上工作。1历史代码:优质资产还是历史包袱?事物总是有两面的,一面是好的,一面就不那么好了。历史代码也是如此.
2020-12-23 21:01:25 133
原创 存储过程的使用场景
http://tommwq.tech/blog/2020/12/22/284决定是否使用存储过程,其实是在权衡:应当将计算移动到数据,还是将数据移动到计算。计算过程可以抽象为以下3个步骤:读数据,计算,写数据。或者说,操作=存取数据+计算。如果需要的数据量较大,存取数据容易成为瓶颈,这时应当将计算移动到数据。反之,如果需要的数据较少,但是计算较为复杂,应当将数据移动到计算。现在来看存储过程。存储过程运行在数据库中,数据移动距离短,但计算能力有限。因此适合于需要读取大量的记录,而计算规则相对简单的
2020-12-22 19:59:47 770
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人