架构设计:为什么说复用是邪恶的?

《编程原则》 大部分时候,技术的决策是专制的。如果我在这个技术领域有丰富的经验,如果我解决过足够多的问题,哪怕我只是在这个项目中待的足够久,那么对于当下任何一个新的问题,我给出的解决方案一定会更完善。 阅读详情

点击上方“芋道源码”,选择“设为星标”

管她前浪,还是后浪?

能浪的浪,才是好浪!

每天 10:33 更新文章,每天掉亿点点头发...

源码精品专栏

 

来源:zhuanlan.zhihu.com/

p/508877002

254fff9af334e298ba19be7ffd50d3ac.jpeg


在系统设计和写代码的过程中,我经常会听到「复用」这个词,以「复用」为目的来设计技术,业务,组织架构。例如:

  • 抽象出一个类,函数,UI 组件,用于不同的场景

  • 抽象出一个微服务,越细越好,这样可以灵活的组合

  • 抽象出一个业务中台,沉淀各种基础业务功能,供全公司使用

  • 组织(管理)架构中,抽象出一个职能竖井(后端,前端,QA,财务),被不同的产品使用

  • 产品设计中要完成一个性能功能,发现跟之前一个功能相似,就复用之前的功能设计,改改继续用

为什么我们喜欢复用呢?

  • 主要目的:既然一部分功能已经存在,为什么还要自己造呢?直接拿来用,这样我可以做得更少,所以能够提升个人的生产效率。

  • 接受的教育:一直以来的教育,大部分工程师都学习过 DRY principle;《设计模式》的的英文书名就是 《可复用面向对象软件的基础》,都在强调复用。

  • 编程习惯:在面向对象语言里,工程师习惯了继承,而继承对于大部分人来说的目的就是复用

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro

  • 视频教程:https://doc.iocoder.cn/video/

认为复用可以提高效率的推理逻辑是怎样的?

  • 如果我们要写一个系统的所有代码,我们需要写大量的代码。

  • 如果我们能从其他地方重用一些以前写过的代码,我们就能写更少的代码。

  • 我们能重用的代码越多,我们写的代码就越少。

  • 我们写的代码越少,我们就会越早完成系统!

这样的推理逻辑是存在如下误区:

  • 所有的代码(功能)需要相同的时间来写

  • 写代码是完成系统的最主要工作

如果你要写得代码依赖很多其他的「复用」模块,你就要去理解不同的「复用」模块提供的接口,很多时候只看文档都不行;如果「复用模块」的接口不是正好是适用你的场景,你就必须在讲究使用接口和对方排期之间进行选择。

此外对于如何抽象出一个公共业务模块,大部分人都没什么标准,公共业务模块的负责人成了业务的外包,效率更低。

另一点是任何维护生产环境系统的人都知道写代码只是整个工作中一小步,而且是确定性最高的一步,之后维护才是最占用时间的。我们需要不断地进行调试,部署,再调试,部署。一个用于很多依赖的模块相对依赖少的模块做这些工作的难度是高很多的。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud

  • 视频教程:https://doc.iocoder.cn/video/

你说复用带来了这么多问题,那我们平时使用各种框架,基础算法库都要自己写一份吗?

肯定不需要自己再写一份,我们平时会使用各种编程语言(Java,Go),框架,库。我们使用这些没有任何问题,因为这是共识和标准,他们是足够「通用,一般化」,并不是为了某个业务或者某个公司定制的。先有「共识,标准」,再谈复用,绝对不是随意的拿过来用。

那我设计系统时,尽量将我的设计通用化就好了(例如拆很多个 CRUD 的微服务),这样就能更多的进行复用,提高生产效率对吗?

复用不是系统要追求的目标。很多人认为更多模块的「复用」,就可以做到像乐高一样快速搭建系统,但是很多复用并不是乐高,而是器官移植,不仅不能提高效率,要不断面对各种各样的排异反应,降低了速度和稳定性。很多创业公司快速发展时系统腐化的主要问题就出现在了强行复用上。强行复用的案例很常见,例如:

  • 上百个字段的数据表(例如订单表,数据表),不清楚哪个字段在哪个场景下有效

  • 根据名词来设计系统,出现业务中台,例如订单中台,电商中台,各部门之间不断地扯皮

  • 出来无数个小的微服务,然后搞个统一的业务编排调度层(所谓的 gateaway)来处理业务,可能还抽象 DSL;上线十分复杂,需要发布 N 各模块;调度模块是系统大单点,稳定性迭代速度都是问题

如果有一个好的设计,我们需要谨记《Hints for Computer System Design》中的「Use a good idea again instead of generalizing it. A specialized implementation of the idea may be much more effective than a general one.」

那系统设计好的标准是什么?衡量的维度有优先级吗?

两个评价标准自治性和一致性:

  • 自治性:受其他模块的影响程度,观测模块的接口是否稳定。可以使用AutonomyMetrics[1] 进行衡量

  • 一致性:应该使用一个模块的地方使用一个模块的程度,也可以衡量是否过早,过度抽象了。可以使用 ConsistencyMetrics[2]

在业务层次是否要从多个业务模块中抽象出一个底层模块,可以通过多个业务模块的这部分公共逻辑部分是否要一起进行改变进行判断,如果不是需要一起变化的就不要抽象出公共模块。

根据个人经验如果你在要从各个业务模块进行抽象出一个模块保持一致与保持在模块保持自治之间犹豫时,要毫不犹豫优先选择「自治」。

总结

大部分情况下系统的核心复杂度不会减少, 只是转移;不会因为所有代码一个人写,会比分成两个人写更快,分工是应该且必须的。但是请注意的是:

  • 不要为了复用随意通用化,抽象化,复用不是目的。如果要通用化就拿ConsistencyMetrics[2] 来判断是否是抽象合理的。

  • 不要随意复用其他的模块,自治优先,用 AutonomyMetrics[1] 衡量;如果要复用一定要确保共识和标准优先,形不成共识和标准就不用复用。

相关链接:

  1. https://autonomy.design/Part1/AutonomyMetrics.html

  2. https://autonomy.design/Part1/ConsistencyMetrics.html

参考链接:

  1. https://zhuanlan.zhihu.com/p/356202989

  2. https://udidahan.com/2009/06/07/the-fallacy-of-reuse/

  3. https://zhuanlan.zhihu.com/p/138145081

  4. https://zhuanlan.zhihu.com/p/410049005



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:

58754f61869e24809ca32ccd72b8f6e7.png

已在知识星球更新源码解析如下:

a6854dd2e721d7b7ea009011c38f999c.jpeg

0027b9a5265b2443150640214783540c.jpeg

0b70b94b721d85939117dabbaf3e28e4.jpeg

20ed932cc4cb4538028c1b6a28df960b.jpeg

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
数据分享:中国历年省、市、县行政区划shp(1949~2023年共计75年) 中华人民共和国县级以上行政区沿革》(三册,1949-1983年)“The Atlas of Changes of Administrative Regions of China”;《中华人民共和国行政区划沿革地图集》The yearly publications of “The Administrative Regions”, 1985-2014;每年的出版行政区划简册(1985-2014年)行政区划网:www.xzqh.org。行政区划网:www.xzqh.org。 阅读详情

相关推荐

电源完整性之Cadence Sigrity Power DC_电热协同仿真

之前和大家分享过电源完整性之仿真设计原理链接: link.今天接着上一篇文章总结一下电源直流压降的的仿真操作流程及一些simulation中的设置参数,用到的是Cadence Sigrity 中的Power DC组件,来操作一下电热协同仿真,下面开始享受仿真的快乐吧: 第0步:仿真简介 电热协同仿真把电和热相互的影响考虑到了一起。因为电导率并不是固定不变的,而是和温度有关,随着温度的升高导电率会下降。同样电流流径电阻的时候会产生热量,此热量为焦耳热。因此为了获得准确的仿真信息,应考虑电与热的互相影响,进行电

刘小同学的博客 1万+

架构设计的悖论,复用是美好的还是邪恶的

错误的抽象、错误的代码复用,所引发的复杂性无限蔓延,对系统的危害比面条代码强大一百倍。复用与扩展,业务与技术,到底哪些该复用哪些不该复用,好像变成了一个哲学问题。如果说“正确的抽象”是一个 100 分的美丽乌托邦,那面向复杂性隔离的整洁架构,会不会是一个稳定的 80 分。面向复杂性隔离的整洁架构,我好像有了一些新的想法... To Be Continue。

阿里技术 1516

React项目实战:用AntV G6打造可折叠组织架构图(附完整代码)

本文详细介绍了如何在React项目中使用AntV G6库构建一个功能完整的可折叠组织架构图。通过实战代码演示了从环境搭建、自定义节点、折叠状态管理到性能优化的全流程,重点解决了企业级应用中处理复杂树形数据、实现流畅交互等核心问题,并提供了可直接复用的组件代码。

weixin_29016315的博客 312

软件的可维护性和可复用性

弟子规,圣人训。 首孝悌,次谨言。 泛爱众,而亲仁。 有余力,则学文。

老焦沉淀淀 1619

H3C设备VRF配置实战:5步搞定多业务网络隔离(附排错技巧)

本文详细介绍了在H3C设备上配置VRF(虚拟路由转发)实现多业务网络隔离的实战方法。通过五步配置流程,从创建VPN-instance、绑定接口到配置独立路由表,帮助网络工程师在单台设备上构建逻辑隔离的企业级网络,并分享了高级路由配置与常见排错技巧。

gold8的专栏 939

脑机接口最新发展动态报告 (2024-2025)

脑机接口动态

高山 4108

是什么阻碍了代码的重用?问题是否应该只解决一次即可?

原文链接:https://www.zhihu.com/question/21011591 作者:悟网不欢链接:https://www.zhihu.com/question/21011591/answer/18268958来源:知乎著作权归作者所有,转载请联系作者获得授权。 作为曾经对复用问题非常关心的前软件行业从业人员,把知乎的第一答献给这个问题。我相信许多对复用抱怨的人,可能了误解的复用的含...

weixin_30300225的博客 112

从4A架构的角度出来 帮我分析一下:数字化转型深水区:企业架构如何成为价值重构的核心引擎?

4A 架构的本质是构建企业的数字神经系统,通过业务感知、数据传输、决策执行、技术支撑的闭环,实现从效率提升到生态重构的质变。正如华为通过该架构实现全球研发资源统一调度,某零售集团借此打造线上线下融合的新零售体系,当业务、数据、应用、技术四个维度形成共振时,企业将获得持续进化的数字免疫力,在不确定的市场环境中保持韧性生长。这一过程不仅需要技术工具的升级,更依赖组织文化的变革 —— 从 “部门墙” 到 “能力网” 的转型,才是数字化转型深水区的终极挑战。

金牌架构师 1047

回归设计的质量属性,来看“复用是美好的还是邪恶的”

本周阿里技术公众号发表了率鸽老师的文章《架构设计的悖论,复用是美好的还是邪恶的》,文章提到:“错误的抽象、错误的代码复用,所引发的复杂性无限蔓延,对系统的危害比面条代码强大一百倍”。我赞同这个观点。不过,究竟什么是“错误的抽象”,什么又是“正确的抽象”呢?什么时候的复用是正确的,什么时候的复用又是不正确的呢?是不是“抽象层次越高,表达能力越低,越难以理解”?我也来写篇文章,说一下我的理解,希望...

pengxin_ce的博客 216

【Go语言实战】(2) Gin+Vue 电子商城

618来!!不用纠结去哪里剁手了!直接自己安排一个商场不香吗??

面向生活编程 4827

【重识云原生】第四章云网络4.7.5节vDPA方案——virtio的半硬件虚拟化实现

vDPA(vhost Data Path Acceleration)即是让virtio数据平面不需主机干预的解决方案。该框架由Redhat提出,实现了virtio数据平面的硬件卸载。控制平面仍然采用原来的控制平面协议,当控制信息被传递到硬件中,硬件完成数据平面的配置之后,数据通信过程由硬件设备(智能网卡)完成,虚拟机与网卡之间直通。中断信息也由网卡直接发送至虚拟机不需要主机的干预。......

junbaozi的专栏 2190

020 第一性原理 + 系统一致性校验:明太祖朱元璋民生治理架构与逻辑正本

核心目标:重建天下秩序、保护底层民生、约束官吏贪腐、保障王朝系统长期稳定;核心动作:搭建全域民生保障、设计反贪吏治系统、制定稳定律法、优化集权安全架构;核心特征:对特权 / 贪腐严苛,对底层百姓宽仁,资源全面投向民生与稳定;标签化证伪:「纯残暴、嗜杀、全民压迫」等叙事,与行为、资源、制度、国祚全面矛盾,不具备逻辑有效性。先看系统长期结果(国祚、文明延续、架构继承),证伪极端标签;再校验行为一致性,剔除孤证与层累伪叙事;拆解底层架构设计,区分架构价值与执行 BUG;最后归因叙事偏差来源。

chuangshitianzun的博客 293

livox雷达斜装修改

指的是,使用外部的陀螺仪的话,雷达到外部陀螺仪的转换,而mid360的陀螺仪是内置在360里面的,且方向和点云方向是一致的,所以不能通过修改此处去改变陀螺仪方向。同时livox_ros_driver2中的MID360_config.json里面的。这里面的外参,只能改变点云相对陀螺仪的位姿,而不能将陀螺仪映射到你期望的倾斜角度。fast_lio中的mid360.yaml中的外参。

z1872385的博客 2713

程序员修炼之道 04:务实的方法 ①

本章介绍一些提示和技巧。无论是编写代码还是做架构设计,又或者是写文档或估算进度,这些提示和技巧适用于软件开发的所有层级。只要在开发过程中牢记这些基本原则,你就能写出更好、更快、更健壮的代码,而且代码可读性更高。

朱工的专栏 1020

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

贯彻单点真理,打造KISS项目

零、 编程的核心困难的是什么?复杂。编程是很复杂的工作,以至于作为一门工科显得很不严谨,只要运作不出问题就当做没问题。编程最核心的技巧是抽象和间接。抽象是简化核心问题的功...

ifeves的博客 218

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

C++ 会议第一天

转自:云风的 BLOG链接:http://blog.codingnow.com/2009/12/cpp2009.html风云前辈,作为程序员我所致敬与学习的榜样。最近也是项目在一轮一轮的UAT之后终于可以有了比较闲的时间了,可以来好好看看好的文章,了解新的动态,学习新的东西。不然心里总有种不踏实的感觉。这篇文章正好是说大牛讨论的大项目的一些不成功,我也有些同感。 Lippm

攀升·Jawf 965

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

暗黑破坏神2存档编辑器:从二进制解析到可视化编辑的完整技术实现

在游戏开发与修改领域,暗黑破坏神2(Diablo 2)的存档系统一直以其复杂的二进制结构和丰富的数据类型而闻名。d2s-editor项目为开发者提供了一个完整的解决方案,将神秘的.d2s文件转换为可交互的Web界面,实现了从底层数据解析到前端可视化编辑的全流程技术栈。 ## 项目架构与技术栈解析 d2s-editor采用了现代Web开发技术栈,基于Vue 3构建前端界面,结合专业的游戏数据解析

gitblog_00567的博客 412

《阿里JAVA编码规范》读后笔记

正所谓脑袋空空,口袋空空,坚持每天学一点东西,坚持每天记录所见所学 :P这两天耐着性子把《阿里JAVA编码规范》看完了,觉得收获良多,先记载下自己的学习笔记,等抽空了再尝试把里面的内容结构化一下方便以后速查,惯例先放出下载地址,大公司做事情都比较有始有终,即使是编码规范文档,也是本着经营产品的心态去维护的,这份规范阿里巴巴有不断地迭代更新,大家可以到云栖论坛下载最新的版本查看。 阿里JAVA编码

gaoyib6的博客 1843

DnfHelper-Python深度解析:游戏自动化引擎的技术实现与实战指南

在当今游戏生态中,重复性操作已成为玩家体验的主要痛点。对于《地下城与勇士》这类需要大量重复刷图的游戏,手动操作不仅耗时耗力,还容易导致玩家疲劳。传统的手动操作方式存在效率低下、操作误差大、无法长时间持续运行等问题。DnfHelper-Python项目正是为了解决这些痛点而诞生的技术解决方案。 ## 架构设计:模块化游戏自动化引擎 ### 核心架构分层解析 DnfHelper-Python采用

gitblog_00237的博客 337

从零构建健壮数据采集系统:Python爬虫实战与反爬策略解析

网络爬虫作为自动化数据采集的核心技术,其工作原理是通过模拟浏览器行为向目标服务器发送HTTP请求,解析返回的HTML、JSON等结构化数据,并提取所需信息。这项技术的价值在于能够高效地从海量网络资源中获取公开数据,为数据分析、机器学习模型训练和市场研究提供原材料。在实际应用场景中,爬虫技术广泛用于舆情监控、价格追踪、学术研究等领域。然而,随着反爬虫机制的日益完善,如频率限制、动态内容加载和行为指纹识别,构建一个健壮的数据采集系统需要综合考虑模块化架构、错误处理和合规策略。本文以Python的requests

weixin_30861459的博客 326

.NET MVC学习笔记(一)

看了些关于MVC的资料,做一些MVC的笔记。 分解关注点 在MVC世界里有个很重要的观念--“分解关注点”(Separation of Concerns),指的是:当你进行软件开发时,可一直关注当前的对象,而不会受到同样的系统中其它对象的干扰,进而专注于完毕开发工作。如此一来,不但easy提升软件质量,也能够加快对代码的理解速度。 分解关注点观念的特征与优势 ...

weixin_30485291的博客 97

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 303

第三篇 第 6 课

前置:第三篇第 1 课(stdx 引入),第二篇第 1 课(std.regex)。环境:仓颉 SDK 1.2.0。本文所有代码与输出均逐行实测。

weixin_41618057的博客 527

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 355

信创环境下PageOffice文档控件适配与实践

信创适配做到文档控件这一层,拼的已经不是"有没有国产版本",而是同一个功能在两类终端上是否真的等价。等价的标准很具体:同一次点击能得到同样的结果,同一份公文能得到同样的版式,同一个项目不需要维护两套代码。这背后是三件并不轻松的工作:服务端用一套接口同时支撑两类终端,客户端把两种系统与四种芯片的安装包分发清楚,文档内核层由产品侧跟着 WPS 的版本走。浏览器这一层的压力,则被收进了产品自己的窗口里——升级节奏由产品掌握,不再交给运气。

zi_wu_xian的专栏 332
上一篇: SpringBoot + Flyway,自动化实现数据库版本控制
下一篇: 最强 IntelliJ IDEA 2022.3 发布,这次不追了。。。
公众号-芋道源码
博客等级 码龄10年 1634粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值