【学习iOS高质量开发】——接口与API设计

news2024/11/20 15:39:44

文章目录

  • 一、用前缀避免命名空间冲突
    • 1.为什么用前缀避免明明冲突
    • 2.应当如何避免
    • 3.要点
  • 二、提供“全能初始化方法”
    • 1.什么是全能初始化方法
    • 2.如何重写初始化方法
    • 3.一个类有多个全能初始化方法要注意的问题
    • 3.要点
  • 三、实现description方法
    • 1.什么是description方法
    • 2.在description方法中使用字典输出
    • 3.什么是debugDescription
    • 4.要点
  • 四、尽量使用不可变对象
    • 1.什么是不可变对象
    • 2.要点
  • 五、使用清晰而协调的命名方式
    • 1.为什么使用清晰而协调的命名方式
    • 2.命名规则
      • 方法命名的规则:
      • 类与协议的命名规则:
    • 3.要点
  • 六、为私有方法名加前缀
    • 1.为什么
    • 2.要点
    • 七、理解Objective-C错误模型
    • 1.如何理解
    • 2.要点
  • 八、理解NSCopying协议
    • 1.什么是NSCopying协议
    • 2.深拷贝和浅拷贝
    • 3.要点


一、用前缀避免命名空间冲突

1.为什么用前缀避免明明冲突

OC中没有其他语言那种内置的命名空间机制(namespace),所以我们在对文件命名时要避免潜在的命名冲突,若是发生重名冲突,那么应用程序相应的链接过程就会出错,因为其中出现了重复的符号。例如:
在这里插入图片描述
这个错误就是因为两份代码都各自实现的EOCTheClass类导致该类所对应的类符号和“元类”符号各定义了两次。又恰好出现在同一个项目中并且重名,导致编译器无法识别,而出错了。

比无法链接更糟糕的清况是,在运行期载入了含有重名类的程序库。此时,“动态加载器”就遭遇了“重名符号错误”,很可能会令整个应用程序崩溃。

2.应当如何避免

避免此问题的唯一办法就是变相实现命名空间:为所有名称都加上适当前缀。所选前缀可以是与公司、应用程序或二者皆有关联之名。即使加了前缀也可能出现命名冲突,但是几率会小很多。

使用Cocoa创建应用程序时一定要注意,Apple宣称其保留使用所有“两字母前缀”的权利,所以你自己选用的前缀应该是三个字母的。

不仅是类名,应用程序中的所有名称都应加前缀。如果要为既有类新增“分类”,那么一定要给“分类”及“分类”中的方法加上前缀,开发者可能会忽视另外一个容易引起命名冲突的地方,那就是类的实现文件中所用的纯C函数及全局变量,在编译好的目标文件中,这些名称是要算做“顶级符号”的。

3.要点

  • 选择与你的公司、应用程序或者二者皆有关联的名称作为类名的前缀,并在所有代码中均使用这一前缀。
  • 若是自己所开发的程序库中用到了第三方库,则应为其中的名称加上前缀。

二、提供“全能初始化方法”

1.什么是全能初始化方法

所有对象均要初始化。初始化时,有些对象可能无须开发者向其提供额外信息,不过一般来说还是要提供的。以iOS的UI框架UIKit为例,其中有个类叫做UITableViewCell,初始化该类对象时,需要指明其样式及标识符,标识符能够区分不同类型的单元格。由于这种对象的创建成本较高,所以绘制表格时可依照标识符来复用,以提升程序效率。我们把这种可为对象提供必要信息以便其能完成工作的初始化方法叫做“全能初始化方法”。

如果创建类实例的方法不止一种,那么这个类就会有多个初始化方法。这当然很好,不过仍然要在其中选定一个作为全能初始化方法,令其他初始化方法都来调用它。NSDate就是个例子,其初始化方法如下:

- (id)init
- (id)initWithString: (NSString *)string
- (id)initWithTimeIntervalSinceNow: (NSTimeInterval)seconds
- (id)initWithTimeInterval: (NSTimeInterval)seconds sinceDate: (NSDate *)refDate
- (id)initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds
- (id)initWithTimeIntervalSince1970: (NSTimeInterval)seconds

正如该类的文档所描述的那样,在上面几个初始化方法中,“initWithTimeIntervalSinceReferenceDate:”是全能初始化方法。也就是说,其余的初始化方法都要调用它。于是,只有在全能初始化方法中,才会存储内部数据。这样的话,当底层数据存储机制改变时,只需修改此方法的代码就好,无须改动其他初始化方法。
比如说,我们要编写一个表示矩形的类。其接口可以这样写:

#import <Foundation/Foundation.h>

@interface EOCRectangle : NSObject
@property (nonatomic, assign, readonly) float width;
@property (nonatomic, assign, readonly) float height;
@end


2.如何重写初始化方法

首先需要在你新的初始化方法中的调用这个类的“全能初始化方法”,如果他是继承关系的话,那么就使用super来调用父类的初始化方法,调用结束之后就可以为想要实现的初始化方法添加逻辑,总而言之,全能初始化方法的调用链一定要维持。**如果子类的全能初始化方法与超类方法的名称不同,我们总应覆写超类的全能初始化方法,避免子类调用父类的全能初始化方法。**但是,有时候我们可能不想覆写超类的全能初始化方法,因为那样做没有道理,那么我们就可以覆写超类的全能初始化方法,让在调用这个方法的时候抛出异常,这样就可以确保用户一定使用的是你自己定义的方法了。

3.一个类有多个全能初始化方法要注意的问题

通常我们遇到的类都只有一个全能初始化方法,但是偶尔也有类具有多个全能初始化方法。

由于这两种初始化方法的解码方式不同,而且我们也不能人为的改变其解码的方式,那么我们就只能顺其自然,他有两种我们也重写两种初始化方法,注意: 重写的这两种初始化方法一定是分别调用过之前的两种全能初始化方法的,并且表明这两种新的初始化方法分别适用于那种情况。

反正,总的来说,我们就是要维持原来类的调用链,每个子类的全能初始化方法都应该调用其超类的对应方法,并逐层向上。因为其父类有两个全能初始化方法,这两种初始化方法定义出来的数据可能是不同的,若是你在子类中调用了错误的父类初始化方法,它就会可能因为数据类型的问题使程序发生错误。

3.要点

  • 在类汇总给你提供一个全能初始化方法,并与文档里指明。其他初始化方法均应调用此方法。
  • 若全能初始化方法与超类不同,则需覆写超类中的对应方法。
  • 如果超类的初始化方法不适用于子类,那么应该覆写这个超类方法,并在其中抛出异常。
  • 重写初始化方法也要注意如果子类的全能初始化方法与超类方法的名称不同,我们总应覆写超类的全能初始化方法,避免子类调用父类的全能初始化方法。

三、实现description方法

1.什么是description方法

在调试程序的的时候经常要打印并查看对象信息。此时我们就可以用到description方法,其实description就是对这个对象本身的描述。例如:

NSLog(@"object = %@", object);

这里的description描述的内容就会替代这个%@。又例如:

NSArray *object = @[@"A string", @(123)];
NSLog(@"object = %@", object);


这里会输出:

object = {
	"A string"
	123
}


如果是一个自定义的类,那么它就会输出该类的地址:

object = <EOCPerson: 0x7fd9a1600600>

这是因为你并没有覆写其description方法,只有在自己的类里覆写description方法,这个对象的描述才会改变,否则打印信息时就会调用NSObject类所实现的默认方法。例如:

- (NSString *) description {
	return [NSString stringWithFormat:@"<%@: %p, %@>",
			[self class],
			self,
			@{@"latitude":_title,
			@"latitude":@(_latitude),
			@"longitude":@(_longitude)}
		];
} 

输出:
location = <EOCLocation: 0x7f98f2e01d20, {
	latitude = "51.506"
	longitude = 0;
	title = London;
}>

description没有什么固定的套路输出什么,就比如,你一个字符串的description和一个数组的description肯定是不一样的,你肯定得根据你要输出的对象来考虑description方法的。

2.在description方法中使用字典输出

在自定义的description方法中,把待打印的信息放到字典里面,然后将字典对象的description方法所输出的内容包含在字符串里并返回,这样就可以实现简易的信息输出方式了。

3.什么是debugDescription

这个也是一种描述方法,和description差不多,就是描述的位置不一样,description是在函数调用类的时候触发方法才输出的,而debugDescription是在控制台中使用命令打印该对象时才调用的。当然加断点查看时也可以看到debugDescription的描述。

如果你在description不想将一些内容输出的话,你就可以将那些数据写在debugDescription中,让程序员自己调试时可以方便的看到这些数据,而description方法就输出你想要让用户看到的信息就行。

4.要点

  • 实现description方法返回一个有意义的字符串,用以描述该实例。
  • 若想在调试时打印出更详尽的对象描述信息,则应实现debugDescription方法。

四、尽量使用不可变对象

1.什么是不可变对象

不可变对象,它指的是这个类里边的属性是不能直接被修改的,要实现这种功能,我们就需要用到我们的readonly(只读)修饰符。默认情况下,属性是readwrite(即可读又可写)的,这样修饰出来的类都是“可变的”。例如:


@property (nonatomic, copy, readonly) NSString *identifier; 
@property (nonatomic, copy, readonly) NSString *title;
@property (nonatomic, assign, readonly) float latitude;

有时可能想修改封装在对象内部的数据,但是却不想令这些数据为外人所改动。这种情况下,通常的做法是在对象内部将readonly属性重新声明为readwrite。当然,如果该属性是nonatomic的,那么这样做可能会产生“竞争条件”,即在对象内部写入某属性时,对象外的观察者也许正读取该属性。若想避免此问题,我们可以在必要时通过“派发队列”等手段,将(包括对象内部的)所有数据存取操作都设为同步操作。就像这样:

@property (nonatomic, copy, readwrite) NSString *identifier; 

现在,这个属性就只能用在实现代码内部设置这些属性了,但其实,在对象外部还可以通过“键值编码”技术来设置这些属性,就像“setValue:forKey:”方法。“点语法”也可以,因为点语法就是调用set方法的。这样做虽说可以改动,但是却违背了本心,还会导致数据不同而出现问题,所以不建议更改。

[pointOfInterest setValue:@"abc" forKey:@"identifier"];


这样子可以改动属性值,因为KVC会在类里查找“setIdentifier:”方法,并借此修改此属性。即使没有于公共接口中公布此方法,它也依然包含在类中。不过,这样做等于违规地绕过了本类所提供的API,要是开发者使用这种“杂技代码”的话,那么得自己开应对可能出现的问题。
还有一种可以修改数据的方法就是直接用类型信息查询功能查出属性所对应的实例变量在内存布局中的偏移量,以此来人为设置这个实例变量的值。这样做比绕过本类的公共API还要不合规范。所以不应该因为这个原因而忽视所提的建议,大家还是要尽量编写不可变的对象。

2.要点

  • 尽量创建不可变的对象
  • 若某属性进可于对象内部修改,则在“class-continuation分类”中将其由属性扩展为readwrite属性
  • 不要把可变的collection作为属性公开,而应提供相关方法,以此修改对象中的可变collection

五、使用清晰而协调的命名方式

1.为什么使用清晰而协调的命名方式

命名时要简洁明了,让用户直接知道该方法是怎么使用的,这样的好处就是,代码读起来像日常语言里的句子。我们通常使用“驼峰命名法”,就是以小写字母开头,其后每个单词首字母大写,不论是类还是属性都可以这样命名。

2.命名规则

方法命名的规则:

  • 如果方法的返回值是新创建的,那么方法名的首个词应是返回值的类型,除非前面还 有修饰语,例如localized String。属性的存取方法 不遵循这种命名方式,因为一般认 为这些方法不会创建新对象,即便有时返回内部对象的一份拷贝, 我们也认为那相当 于原有的对象。这些存取方法应该按照其所对应的属性来命名。
  • 应该把表示参数类型的名词放在参数前面。
  • 如果方法要在当前对象上执行操作,那么就应该包含动词;若执行操作时还需要参数, 则应该在动词后面加 上一个或多个名词。
  • 不要使用str 这种简称,应该用string 这样的全称。
  • Boolean 属性应加is 前缀。如果某方法返回非属性的Boolean 值,那么应该根据其功 能,选用has 或is 当前缀。
  • 将get 这个前缀留给那些借由“输出参数〞来保存返回值的方法,比如说,把返回值填充到〝C语言式数组” ( C - style array ) 里的那种方法就可以使用这个词做前缀 。

类与协议的命名规则:

应该为类与协议的名称加上前缀,以避免命名空间冲突,而且应该像给方法起名时那样把词句组织好,使其从左至右读起来较为通顺。基本命名规则就是:命名方式应该一致,如果要从其他的类中继承子类,那么就要遵守其原本的命名惯例。 例如:UIView它的子类就应该是***View,表明其来历。

3.要点

  • 起名时应遵从标准的OC命名规范,这样创建出来的接口更容易为开发者所理解。
  • 方法名要言简意赅,从左至右读起来要像个日常用语中的句子才好。
  • 方法名里不要使用缩略后的类型名称。
  • 给方法名起名时的第一要务就是确保其风格与你自己的代码或所要集成的框架相符。

六、为私有方法名加前缀

1.为什么

通常我们在写方法时,并没有对其进行私有共有分类,导致调试时可能很麻烦,现在为私有方法加上前缀,这样便于修改方法或方法签名。唯一注意的是:一定不要只使用_作为前缀,因为苹果公司使用的就是_作为私有方法的前缀的,你自己定义的私有方法名有可能就会和人家自带的冲突。

驼峰命名法

方法和变量名的首个单词的首个字母小写,然后后面的每个单词的首字母大写。类名也用驼峰命名法,另外,类名一般还有三个前缀字母。

2.要点

  • 给私有方法的名称加上前缀,这样可以很容易地将其同公共方法区分开。
  • 不要单用一个下划线做私有方法的前缀,因为这种做法是预留给苹果公司用的。

七、理解Objective-C错误模型

1.如何理解

当前很多编程语言都有“异常”(exception)机制,OC也不例外。
首先要注意的是,“自动引用计数”(Automatic Reference Counting, ARC)在默认情况下不是“异常安全的”(exception safe)。具体来说,这意味着:如果抛出异常,那么本应在作用域末尾释放的对象现在不会自动释放了。如果想生成“异常安全”的代码,可以通过设置编译器的标志来实现,不过这将引入一些额外代码,在不抛出异常时,也照样要执行这部分代码。需要打开的编译器标志叫做-fobjc-arc-exceptions。可是在释放资源之前如果抛出异常了,那么该资源就不会被释放了:

id someResource = /*...*/;
if (/*check for error*/) {
	@throw [NSException exceptionWithName:@"ExceptionName" reason:@"There was an error" userInfo:nil];
}
[someResource doSomething];
[someResource release];


在抛出异常前先释放someResource,这样做当然能解决此问题,不过要是待释放的资源有很多,而且代码的执行路径更为复杂的话,那么释放资源的代码就容易写的很乱。此外,代码中加入了新的资源之后,开发者经常会忘记在抛出异常前先把它释放掉。
OC语言现在采用的方法是:只在极其罕见的情况下抛出异常,异常抛出之后,无须考虑恢复问题,而且应用程序此时也应该退出。也就是说,不用再编写复杂的“异常安全”的代码了。
异常只用来处理严重错误(fatal error,致命错误);对于“不那么严重的错误”(nonfatal error,非致命错误),OC语言所采用的编程范式为:令方法返回nil/0,或是使用NSError,以表明其中有错误发生。例如:

 - (id)initWithValue:(id)value {
	if (self = [super init]) {
		if (/*Value means instance can't be created*/) {
			self = nil;
		} else {
			//Initialize instance
		}
	}
	return self;
}

这种情况下,如果if语句发现无法用传入的参数值来初始化当前实例,那么就把self设置成nil,这样的话,整个方法的返回值也就是nil了。调用者发现初始化方法并没有2把实例创建好,于是便可以知道其中发生了错误。
NSError的用法更加灵活,因为经由此对象,我们可以把导致错误的原因回报给调用者。NSError对象里封装了三条消息:

  1. Error domain(错误范围,类型为字符串)产生错误的根源,通常用一个特有的全局变量来定义。
  2. Error code(错误码,类型为整数)独有的错误代码,用以指明在某个范围内具体发生了何种错误。某个特定范围可能会发生一系列相关错误,这些错误通常采用enum定义。
  3. User info(用户信息,类型为字典)有关错误的额外信息,其中或许包含一段“本地化描述”(localized description),或许还含有导致该错误发生的另外一个错误,经由此种信息,可将相关错误串成一条“错误链”(chain of errors)。

2.要点

  • 只有发生了可使整个应用程序崩溃的严重错误时,才应使用异常。
  • 在错误不那么严重的情况下,可以指派“委托方法”来处理错误,也可以把错误信息放在NSError对象里,经由“输出参数”返回给调用者。

八、理解NSCopying协议

1.什么是NSCopying协议

我们经常会使用copy函数,但是若是你自定义的类,他自己就不会实现这个函数,此时就需要你自己来实现了,要实现copy函数就的实现NSCopying协议,该协议只有一个方法:- (id)copyWithZone:(NSZone *)zone;
可以看到方法中有个参数为zone因为以前开发程序时,会据此把内存分成不同的“区”,而对象会创建在某个区里。现在不用了,每个程序只有一个区:“默认区”。所以说,尽管必须实现这个方法,到那时你不必担心其中的zone参数。

copy方法由NSObject实现,该方法只是以“默认区”为参数来调用“copyWithZone:”。所以要实现copy函数,他才是关键。
想要重写copy函数,要声明该类遵从NSCopying协议,并实现其中的方法。

#import <Foundation/Foundation.h>
@interface EOCPerson : NSObject <NSCopying>
@property (nonatomic, copy, readonly) NSString *firstName; @property (nonatomic, copy, readonly) NSString *lastName;
- (id) initwithFirstName: (NSString*)firstName andLastName: (NSString*) lastName;
@end

实现协议中规定的方法:

- (id) copyWithZone: (NSZone*)zone {
	EOCPerson *copy = [[[self class] allocWithZone: zone] initwithFirstName: firstName andLastName: lastName];
	return copy; 
}

2.深拷贝和浅拷贝

深拷贝:在拷贝对象自身时,将其底层数据也一并复制过去。
浅拷贝:在拷贝对象自身时,只拷贝容器对象本身,而不复制其中的数据。
在这里插入图片描述
在这里插入图片描述

3.要点

  • 若想令自己所写的对象具有拷贝功能,则需实现NSCopying协议。
  • 如果自定义的对象分为可变版本和不可变版本,那么就要同时实现NSCopying与NSMutableCopying协议。
  • 复制对象时需决定采用浅拷贝还是深拷贝,一般情况下应该尽量执行浅拷贝。
  • 如果你所写的对象需要深拷贝,那么可考虑新增一个专门执行深拷贝的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1466168.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024 ,Android 15 预览版来了

日前&#xff0c;Android 15 发布了 Preview 1 预览版&#xff0c;预览计划将从 2024 年 2 月持续到 Android 15 公开发布&#xff08;预计 10 月&#xff09;&#xff0c;3月是开发者预览版 2&#xff0c;4 月将推出 Beta 1&#xff0c;5 月将推出 Beta 2&#xff0c;6 月的 B…

大模型平民化技术之LORA

1. 引言 在这篇博文中&#xff0c; 我将向大家介绍LoRA技术背后的核心原理以及相应的代码实现。 LoRA 是 Low-Rank Adaptation 或 Low-Rank Adaptors 的首字母缩写词&#xff0c;它提供了一种高效且轻量级的方法&#xff0c;用于微调预先训练好的的大语言模型。这包括 BERT 和…

7-liunx服务器规范

目录 概况liunx日志liunx系统日志syslog函数openlog 可以改变syslog默认输出方式 &#xff0c;进一步结构化 用户信息进程间的关系会话ps命令查看进程关系 系统资源限制改变工作目录和根目录服务器程序后台话 概况 liunx服务器上有很多细节需要注意 &#xff0c;这些细节很重要…

C++的deque容器->基本概念、构造函数、赋值操作、大小操作、插入和删除、数据存取、排序

#include<iostream> using namespace std; #include <deque> //deque构造函数 void printDeque(const deque<int>& d) { for (deque<int>::const_iterator it d.begin(); it ! d.end(); it) { //*it 100; 容器中的数据不可以修…

【Java网络编程06】HTTPS原理

1. HTTPS基本概念 HTTPS&#xff1a;HTTPS也是一个应用层协议&#xff0c;它在HTTP协议的基础上引入了一个加密层——SSL协议&#xff0c;区别就在于HTTP协议是基于明文传输的&#xff08;不安全&#xff09;&#xff0c;使用HTTPS加密就能在一定程度上防止数据在传输过程中被…

高级语言期末2012级A卷

1.编写函数&#xff0c;输出任意正整数n的位数&#xff08;n默认为存储十进制的整形变量&#xff09; 例如&#xff1a;正整数13&#xff0c;则输出2,&#xff1b;正整数3088&#xff0c;则输出4 #include <stdio.h>int func(int n) {int count0;while(n>0) {n/10;co…

自学Python第十八天-自动化测试框架(二):DrissionPage、appium

自学Python第十八天-自动化测试框架&#xff08;二&#xff09;&#xff1a;DrissionPage、appium DrissionPage环境和安装配置准备工作简单的使用示例控制浏览器收发数据包模式切换 浏览器模式创建浏览器对象访问页面加载模式none 模式技巧 获取页面信息页面交互查找元素ele()…

【学网攻】 第(30)节 -- 综合实验三

系列文章目录 目录 系列文章目录 文章目录 前言 一、综合实验 二、实验 1.引入 实验目标 实验设备 实验拓扑图 实验配置 文章目录 【学网攻】 第(1)节 -- 认识网络【学网攻】 第(2)节 -- 交换机认识及使用【学网攻】 第(3)节 -- 交换机配置聚合端口【学网攻】 第(4)节…

个人博客系列-环境配置-gitee(2)

注册gitee账户 地址&#xff1a;https://gitee.com/ 此步骤省略 新建仓库 执行以下命令 即可 拉取代码 创建目录 mkdir myCode && cd myCode 登录gitee找到项目&#xff0c;点击克隆&#xff0c;拉取代码 连接远程仓库命令 git remote add origin 仓库地址http…

负载均衡.

简介: 将请求/数据【均匀】分摊到多个操作单元上执行&#xff0c;负载均衡的关键在于【均匀】。 负载均衡的分类: 网络通信分类 四层负载均衡:基于 IP 地址和端口进行请求的转发。七层负载均衡:根据访问用户的 HTTP 请求头、URL 信息将请求转发到特定的主机。 载体维度分类 硬…

证件照(兼容H5,APP,小程序)

证件照由uniappuyui开发完成&#xff0c;并同时兼容H5、App、微信小程序、支付宝小程序&#xff0c;其他端暂未测试。 先看部分效果图吧具体可以下方复制链接体验demo 首页代码 <template><view class""><view class"uy-m-x-30 uy-m-b-20"…

2024移动应用的发展趋势,开发者如何抢占变现先机?

2024年对移动应用市场将是变革之年&#xff0c;社交媒体变现方式的瞬息万变&#xff0c;到人工智能的快速崛起&#xff0c;移动应用市场的换代速度逐渐加快&#xff0c;一些新的机遇也在出现。 data.ai推出的2024全球移动市场预测&#xff1a; •TikTok将打破应用商店支出的所…

Linux中的各类时间 与 find命令的常用参数

之前研究wal日志清理的副产物&#xff0c;wal日志名被修改后文件的哪个时间会变&#xff1f;应该如何删除&#xff1f;由此整理一下Linux中atime、mtime、ctime的区别&#xff0c;以及find的常见用法。 一、 Linux中的各类时间 1. 各类时间的定义 Linux中有三种用于文件时间戳…

基于springboot+vue的桂林旅游景点导游平台(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

3个精美的wordpress企业网站模板

WordPress企业网站模板 https://www.zhanyes.com/qiye/6305.html WordPress企业官网模板 https://www.zhanyes.com/qiye/6309.html WordPress律师模板 https://www.zhanyes.com/qiye/23.html

新代码质量评审标准与评分表格

前面发了一个《代码质量评审标准与评分表格》&#xff0c;是比较宽泛的&#xff0c;下面发一个更贴近具体场景的《新代码质量评审标准与评分表格》。 一、引言 本文档旨在为代码质量评审提供一个统一的标准和评分机制&#xff0c;以确保代码质量、可读性和可维护性。通过遵循这…

JAVA代码审计之XSS漏洞

Part1 漏洞案例demo&#xff1a; 没有java代码审计XSS漏洞拿赏金的案例。 所以将就看看demo吧 漏洞原理&#xff1a;关于XSS漏洞的漏洞原理核心其实没啥好说的&#xff0c;网上一查一大堆 反射性XSS漏洞 <% page language"java" contentType"text/html; c…

微服务远程调用Feign

目录 RPC概述 什么是Feign&#xff1f; Ribbon&Feign对比 Feign的设计架构 Spring Cloud Alibaba快速整合Feign Spring Cloud Feign扩展 日志配置 契约配置 通过拦截器实现参数传递 自定义拦截器实现认证逻辑 超时时间配置 RPC概述 微服务之间如何方便优雅的实…

【Linux进阶之路】Socket —— “UDP“ “TCP“

文章目录 一、再识网络1. 端口号2. 网络字节序列3.TCP 与 UDP 二、套接字1.sockaddr结构2.UDP1.server端1.1 构造函数1.2 Init1.3 Run 2.客户端1.Linux2.Windows 3.TCP1. 基本接口2. 客户端3. 服务端1.版本12.版本23.版本34.版本4 三、守护进程尾序 一、再识网络 1. 端口号 在…

给windows server安装nginx服务

一、先安装chocolatey https://chocolatey.org/install 二、查询nginx包 https://community.chocolatey.org/packages 三、安装nginx choco install nginx 四、通过命令行启动/关闭nginx net stop nginx net start nginx 我开发的chatgpt网站&#xff1a; https://chat.xut…