全网资源采集网站搭建

电脑端+手机端+微信端=数据同步管理

免费咨询热线:13114099110

当前位置: 主页 > 新闻资讯

网站代码优化-(如何进行网站代码seo优化)

发布时间:2022-11-15 10:00   浏览次数:次   作者:派坤优化

编写高效的代码是我们的一项基本技能。我们绝不能忽视代码的性能要求。越早考虑性能问题,需要付出的成本就越少,带来的价值就越大。不要等到出现性能问题才进行临时修复。如果前期没有关注代码的性能,那么后期就得加倍努力维护和重构代码。

代码的性能不是在多个块中进行加减乘除的能力,而是如何管理内存、磁盘、网络、内核等计算机资源,实现性能优化。

在本文中,我挑选了三种常见且实用的代码性能优化方法,供大家参考和借鉴。

保持界面简单直观的两个技巧

接口之所以难设计,是因为接口对稳定性的要求比较高。要保证界面的稳定性,最有效的方法就是让界面设计简单直观。在工作中,我总结了两个小技巧,供大家参考。

学会解决问题

设计软件界面,必须从实际问题出发。只有这样,才能找到明确的主线。围绕这条主线进行设计,可以有效避免需求膨胀和过渡设计。

要分解问题,需要遵循两个原则——相互独立和完全耗尽。

例如,是否可以授权用户使用在线服务?这个问题可以分解为两个子问题:

1.用户是注册用户吗?

2、用户密码是否正确?

我们可以用一张思维导图来描述这个分解。

网站代码优化-(如何进行网站代码seo优化)(图1)

这个划分其实是有问题的。因为只有注册用户才会有正确的密码。而且,只有密码正确的用户才能被视为注册用户。这两个小问题之间存在依赖关系,不能说是“相互独立”。

我们要消除这种依赖,这需要两个层次的表达。第一级问题是,这个用户是注册用户吗?这个问题可以进一步分解为两个更小的问题:用户持有的用户名是否注册?用户持有的密码是否匹配?

1.用户是注册用户吗?

用户名是否已经注册?

用户密码是否正确?

网站代码优化-(如何进行网站代码seo优化)(图2)

但这仍然是有缺陷的。如果一个服务是对所有注册用户开放的,那么上面的分解就完成了。否则,我们就错过了一个重要的内容。不同的注册用户可能有不同的服务访问权限。也就是说,如果没有访问权限,即使用户名和密码正确,也无法访问相关服务。

如果加上缺失的,这个问题的分解可以进一步表示为:

1.用户是注册用户吗?

用户名是否已经注册?

用户密码是否正确?

2. 用户是否有访问权限?

网站代码优化-(如何进行网站代码seo优化)(图3)

至此,我们会有一个清晰的思路。

一个界面解决一件事

这里所说的“事”,其实是某种层面的责任。比如授权用户访问是一个完整的、独立的事情。有了逻辑层次,我们就可以分解问题,建立接口之间的联系。

对于一件事的划分,要注意三点。

1、一物归一物,不可两物,不可三物。

2. 这件事是独立的。

3.东西齐全。

下面以一段代码为例,看看如果接口不清晰会出现什么情况。

 复制代码

/**
 * A {@code HelloWords} objectisresponsiblefordetermining how to say
 *"Hello"indifferent language.
 */
classHelloWords{
 privateStringlanguage= "English";
 privateStringgreeting= "Hello";
{1}
 //snipped 
{1}
 /**
 *Setthelanguageofthegreeting.
 *
 * @paramlanguagethelanguageofthegreeting.
 */
 voidsetLanguage(String language){
 //snipped 
 }
{1}
 /**
 *Setthegreetingsofthegreeting.
 *
 * @paramlanguagethegreetingsofthegreeting.
 */
 voidsetGreeting(String greeting){
 //snipped 
 }
{1}
 //snipped 
}
{1}

这段代码涉及到两个元素,一个是(英文、中文等),一个是(你好、你好等),对这两个元素进行了抽象。使用 () 设置问候语的语言,使用 () 设置问候语的问候语。但是这样的设计对用户来说并不友好。因为方法()和()都不能表达一个完整的东西。只有两种方法的结合才能表达一个完整的东西。

这种相互依赖会导致许多问题。例如:

1、使用时,先调用哪个方法?

2、语言和问候语不符怎么办?

3、实现时,是否需要匹配语言和问候语?

4.实施时,语言和问候语如何搭配?

所以我们应该牢记,接口应该尽可能只解决一件事。如果做不到,我们需要减少依赖。

了解更多界面设计,请点击:如何设计简单直观的界面?

学习使用 JMH 并避免性能陷阱

我们如何知道我们编写的代码的性能?其实Java提供了一个性能测试工具JMH,可以直观的帮助我们查看代码的性能缺陷和陷阱。

如何使用JMH

首先,使用 Maven 工具创建一个基准项目:

 复制代码

mvn archetype:generate \
-DinteractiveMode=false \
-DarchetypeGroupId=org.openjdk.jmh \
-DarchetypeArtifactId=jmh-java-benchmark-archetype \
-DgroupId=com.example \
-DartifactId=myJmh \
-Dversion=1.0

然后编译基准:

 复制代码

cd myJmh
$ mvn clean install

最后运行编译测试:

 复制代码

cd myJmh
$ Java -jar target/benchmarks.jar

下面是运行结果,我们需要注意Score那一栏,显示的是每秒可以执行的方法数。次数越多,效率越高。

 复制代码

Benchmark Mode Cnt Score Error Units
MyBenchmark.testMethod thrpt2535.945▒0.694ops/s

让我们通过运行三个字符串来查看这三个字符串的性能差异,并且。为了方便对比,JMH的测试结果写在了注释中。

 复制代码

// JMH throughput benchmark: about 32 operations per second
@Benchmark
publicStringmeasureStringApend(){
String targetString ="";
for(inti =0; i <10000; i++) {
targetString +="hello";
}
returntargetString;
}
// JMH throughput benchmark: about 5,600 operations per second
@Benchmark
publicStringmeasureStringBufferApend(){
StringBuffer buffer =newStringBuffer();
for(inti =0; i <10000; i++) {
buffer.append("hello");
}
returnbuffer.toString();
}
// JMH throughput benchmark: about 21,000 operations per second
@Benchmark
publicStringmeasureStringBuilderApend(){
StringBuilder builder =newStringBuilder();
for(inti =0; i <10000; i++) {
builder.append("hello");
}
returnbuilder.toString();
}

正如您可能看到的那样,使用 的字符串连接操作的性能最差,它比使用 的操作快近 200 倍,而字符串连接操作的速度几乎快 700 倍。

为什么效率这么慢?这是因为每个字符串连接操作都需要创建一个新对象网站代码优化,然后销毁,然后创建。这种模式会消耗大量的 CPU 和内存。

为什么比那快?的字符串操作是 MT 安全的,而 的操作不是。如果我们看一下这两个方法的实现代码,除了线程安全同步之外,几乎没有区别。

通过以上基准测试,我们可以得出以下结论:

1、频繁的对象创建和销毁会损害代码的效率;

2.减少内存分配、复制、释放的频率,可以提高代码的效率;

3. 即使在单线程环境下,使用线程同步仍然会降低代码的效率。

超越线程同步的技巧

我们都知道线程同步不利于效率。在实际工作中,只要打破以下任一条件,就不需要使用线程同步:

使用单线程;

1. 不关心共享资源的变化;

2. 共享资源的行为没有变化。

3、具体工作场景下如何避免线程同步?

学习使用 final 关键字

Java 中的 final 关键字可以将变量变为不可变量。在软件环境中,不可变意味着一旦实例化,就不会改变。

例如,下面的代码没有使用 final 关键字。如果只有一个线程,这段代码没问题。但是网站代码优化,如果有两个线程,一个读取一个写入,则会出现竞争条件,返回不匹配的语言环境和问候语。

 复制代码

classHelloWords {
privateStringlanguage ="English";
privateStringgreeting ="Hello";
voidsetLanguage(Stringlanguage) {
this.language = language;
}
voidsetGreeting(Stringgreeting) {
this.greeting = greeting;
}
StringgetLanguage() {
returnlanguage;
}
StringgetGreeting() {
returngreeting ;
}
}

如果我们使用 final 关键字,则类变量只能在实例化之前被赋值一次。这些变量是不可变的量。如果一个类的所有变量都是不可变的,那么这个类也是不可变的。

 复制代码

classHelloWords{
privatefinalStringlanguage;
privatefinalStringgreeting;
HelloWords(Stringlanguage,Stringgreeting) {
this.language = language;
this.greeting = greeting;
}
StringgetLanguage() {
returnlanguage;
}
StringgetGreeting() {
returngreeting ;
}
}

因此,我们要养成一个习惯。当我们看到一个声明的变量时,我们必须思考这个变量是否可以声明为不可变量?有没有办法修改接口设计或实现代码,使其变为不可变量?在设计类的时候,应该优先考虑这个类是否可以设计成不可变类?这样可以避免很多不必要的线程同步,让代码更高效,界面更易用。

欢迎工作一到五年的Java工程师朋友加入Java程序员开发:

本群免费提供Java架构学习资料(包含高可用、高并发、高性能与分布式、Jvm性能调优、源码、Netty、Redis、Kafka、Mysql、、、、Dubbo、Nginx等知识点结构资料)用每一分每一秒的时间去学习和提升自己,不要再用“没时间”来掩盖自己思想上的懒惰!趁着年轻,好好努力,给未来的自己一个交代!

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。