番禺响应式网站建设电子商务网站建设与管理课程的感想

news/2025/9/23 5:43:13/文章来源:
番禺响应式网站建设,电子商务网站建设与管理课程的感想,沈阳企业网站优化排名方案,免费网站流量统计工具Spring结合自定义注解实现 AOP 切面功能 Spring AOP 注解概述Aspect 快速入门execution 切点表达式 拦截指定类的方法Pointcut(annotation(xx)) 拦截拥有指定注解的方法环绕通知 实现开关目标方法案例1#xff1a;自定义注解切面实现统一日志处理1.自定义日志注解… Spring结合自定义注解实现 AOP 切面功能 Spring AOP 注解概述Aspect 快速入门execution 切点表达式 拦截指定类的方法Pointcut(annotation(xx)) 拦截拥有指定注解的方法环绕通知 实现开关目标方法案例1自定义注解切面实现统一日志处理1.自定义日志注解2声明日志切面组件3.控制层运行结果4.运行结果 案例2自定义注解与切面类1、创建自定义注解2、创建一个类定义方法后使用自定义注解3、定义切面类进行扫描自定义注解并对切入点进行处理 Spring AOP 注解概述 1、Spring 的 AOP 功能除了在配置文件中配置一大堆的配置比如切入点、表达式、通知等等以外使用注解的方式更为方便快捷特别是 Spring boot 出现以后基本不再使用原先的 beans.xml 等配置文件了而都推荐注解编程。 注解功能Aspect切面声明标注在类、接口包括注解类型或枚举上。Pointcut切入点声明即切入到哪些目标类的目标方法。既可以用 execution 切点表达式, 也可以是 annotation 指定拦截拥有指定注解的方法.value 属性指定切入点表达式默认为 “”用于被通知注解引用这样通知注解只需要关联此切入点声明即可无需再重复写切入点表达式Before前置通知, 在目标方法(切入点)执行之前执行。value 属性绑定通知的切入点表达式可以关联切入点声明也可以直接设置切入点表达式注意如果在此回调方法中抛出异常则目标方法不会再执行会继续执行后置通知 - 异常通知。After后置通知, 在目标方法(切入点)执行之后执行AfterReturning返回通知, 在目标方法(切入点)返回结果之后执行.pointcut 属性绑定通知的切入点表达式优先级高于 value默认为 “”AfterThrowing异常通知, 在方法抛出异常之后执行, 意味着跳过返回通知pointcut 属性绑定通知的切入点表达式优先级高于 value默认为 注意如果目标方法自己 try-catch 了异常而没有继续往外抛则不会进入此回调函数Around环绕通知目标方法执行前后分别执行一些代码类似拦截器可以控制目标方法是否继续执行。通常用于统计方法耗时参数校验等等操作。 正常流程【环绕通知-前】- 【前置通知】- 【返回通知】- 【后置通知】-【环绕通知-后】。 2、上面这些 AOP 注解都是位于如下所示的 aspectjweaver 依赖中 3、对于习惯了 Spring 全家桶编程的人来说并不是需要直接引入 aspectjweaver 依赖因为 spring-boot-starter-aop 组件默认已经引用了 aspectjweaver 来实现 AOP 功能。换句话说 Spring 的 AOP 功能就是依赖的 aspectjweaver !-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -- dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactIdversion2.1.4.RELEASE/version /dependency4、AOP 底层是通过 Spring 提供的的动态代理技术实现的在运行期间动态生成代理对象代理对象方法执行时进行增强功能的介入再去调用目标对象的方法从而完成功能的增强。主要使用 JDK 动态代理与 Cglib 动态代理。 5、所以如果目标类不是 Spring 组件则无法拦截如果是 类名.方法名 方式调用也无法拦截。 Aspect 快速入门 1、Aspect 常见用于记录日志、异常集中处理、权限验证、Web 参数校验、事务处理等等 2、要想把一个类变成切面类只需3步 在类上使用 Aspect 注解使之成为切面类切面类需要交由 Sprign 容器管理所以类上还需要有 Service、Repository、Controller、Component 等注解在切面类中自定义方法接收通知 3、AOP 的含义就不再累述了下面直接上示例 /*** 切面注解 Aspect 使用入门* 1、Aspect声明本类为切面类* 2、Component将本类交由 Spring 容器管理* 3、Order指定切入执行顺序数值越小切面执行顺序越靠前默认为 Integer.MAX_VALUE** author wangMaoXiong* version 1.0* date 2020/8/20 19:22*/ Aspect Order(value 999) Component public class AspectHelloWorld {private static final Logger LOG LoggerFactory.getLogger(AspectHelloWorld.class);/*** Pointcut 切入点声明即切入到哪些目标方法。value 属性指定切入点表达式默认为 。* 用于被下面的通知注解引用这样通知注解只需要关联此切入点声明即可无需再重复写切入点表达式* p* 切入点表达式常用格式举例如下* - * com.wmx.aspect.EmpService.*(..))表示 com.wmx.aspect.EmpService 类中的任意方法* - * com.wmx.aspect.*.*(..))表示 com.wmx.aspect 包(不含子包)下任意类中的任意方法* - * com.wmx.aspect..*.*(..))表示 com.wmx.aspect 包及其子包下任意类中的任意方法* /p* value 的 execution 可以有多个使用 || 隔开.*/Pointcut(value execution(* com.wmx.hb.controller.DeptController.*(..)) || execution(* com.wmx.hb.controller.EmpController.*(..)))private void aspectPointcut() {}/*** 前置通知目标方法执行之前执行以下方法体的内容。* value绑定通知的切入点表达式。可以关联切入点声明也可以直接设置切入点表达式* br/* * param joinPoint提供对连接点处可用状态和有关它的静态信息的反射访问br/ p* * * Object[] getArgs()返回此连接点处目标方法的参数目标方法无参数时返回空数组* * * Signature getSignature()返回连接点处的签名。* * * Object getTarget()返回目标对象* * * Object getThis()返回当前正在执行的对象* * * StaticPart getStaticPart()返回一个封装此连接点的静态部分的对象。* * * SourceLocation getSourceLocation()返回与连接点对应的源位置* * * String toLongString()返回连接点的扩展字符串表示形式。* * * String toShortString()返回连接点的缩写字符串表示形式。* * * String getKind()返回表示连接点类型的字符串* * * /p*/Before(value aspectPointcut())public void aspectBefore(JoinPoint joinPoint) {Object[] args joinPoint.getArgs();Signature signature joinPoint.getSignature();Object target joinPoint.getTarget();Object aThis joinPoint.getThis();JoinPoint.StaticPart staticPart joinPoint.getStaticPart();SourceLocation sourceLocation joinPoint.getSourceLocation();String longString joinPoint.toLongString();String shortString joinPoint.toShortString();LOG.debug(【前置通知】 args{},signature{},target{},aThis{},staticPart{}, sourceLocation{},longString{},shortString{}, Arrays.asList(args), signature, target, aThis, staticPart, sourceLocation, longString, shortString);}/*** 后置通知目标方法执行之后执行以下方法体的内容不管目标方法是否发生异常。* value绑定通知的切入点表达式。可以关联切入点声明也可以直接设置切入点表达式*/After(value aspectPointcut())public void aspectAfter(JoinPoint joinPoint) {LOG.debug(【后置通知】kind{}, joinPoint.getKind());}/*** 返回通知目标方法返回后执行以下代码* value 属性绑定通知的切入点表达式。可以关联切入点声明也可以直接设置切入点表达式* pointcut 属性绑定通知的切入点表达式优先级高于 value默认为 * returning 属性通知签名中要将返回值绑定到的参数的名称默认为 ** param joinPoint 提供对连接点处可用状态和有关它的静态信息的反射访问* param result 目标方法返回的值参数名称与 returning 属性值一致。无返回值时这里 result 会为 null.*/AfterReturning(pointcut aspectPointcut(), returning result)public void aspectAfterReturning(JoinPoint joinPoint, Object result) {LOG.debug(【返回通知】,shortString{},result, joinPoint.toShortString(), result);}/*** 异常通知目标方法发生异常的时候执行以下代码此时返回通知不会再触发* value 属性绑定通知的切入点表达式。可以关联切入点声明也可以直接设置切入点表达式* pointcut 属性绑定通知的切入点表达式优先级高于 value默认为 * throwing 属性与方法中的异常参数名称一致** param ex捕获的异常对象名称与 throwing 属性值一致*/AfterThrowing(pointcut aspectPointcut(), throwing ex)public void aspectAfterThrowing(JoinPoint jp, Exception ex) {String methodName jp.getSignature().getName();if (ex instanceof ArithmeticException) {LOG.error(【异常通知】 methodName 方法算术异常ArithmeticException ex.getMessage());} else {LOG.error(【异常通知】 methodName 方法异常 ex.getMessage());}}/*** 环绕通知* 1、Around 的 value 属性绑定通知的切入点表达式。可以关联切入点声明也可以直接设置切入点表达式* 2、Object ProceedingJoinPoint.proceed(Object[] args) 方法继续下一个通知或目标方法调用返回处理结果如果目标方法发生异常则 proceed 会抛异常.* 3、假如目标方法是控制层接口则本方法的异常捕获与否都不会影响目标方法的事务回滚* 4、假如目标方法是控制层接口本方法 try-catch 了异常后没有继续往外抛则全局异常处理 RestControllerAdvice 中不会再触发** param joinPoint* return* throws Throwable*/Around(value aspectPointcut())public Object handleControllerMethod(ProceedingJoinPoint joinPoint) throws Throwable {this.checkRequestParam(joinPoint);StopWatch stopWatch StopWatch.createStarted();LOG.debug(【环绕通知】执行接口开始方法{}参数{} , joinPoint.getSignature(), Arrays.asList(joinPoint.getArgs()).toString());//继续下一个通知或目标方法调用返回处理结果如果目标方法发生异常则 proceed 会抛异常.//如果在调用目标方法或者下一个切面通知前抛出异常则不会再继续往后走.Object proceed joinPoint.proceed(joinPoint.getArgs());stopWatch.stop();long watchTime stopWatch.getTime();LOG.debug(【环绕通知】执行接口结束方法{}, 返回值{},耗时{} (毫秒), joinPoint.getSignature(), proceed, watchTime);return proceed;}/*** 参数校验防止 SQL 注入** param joinPoint*/private void checkRequestParam(ProceedingJoinPoint joinPoint) {Object[] args joinPoint.getArgs();if (args null || args.length 0) {return;}String params Arrays.toString(joinPoint.getArgs()).toUpperCase();String[] keywords {DELETE , UPDATE , SELECT , INSERT , SET , SUBSTR(, COUNT(, DROP ,TRUNCATE , INTO , DECLARE , EXEC , EXECUTE , AND , OR , --};for (String keyword : keywords) {if (params.contains(keyword)) {LOG.warn(参数存在SQL注入风险其中包含非法字符 {}., keyword);throw new RuntimeException(参数存在SQL注入风险params params);}}} }如上所示在不修改原来业务层代码的基础上就可以使用 AOP 功能在目标方法执行前后或者异常时都能捕获然后执行。 execution 切点表达式 拦截指定类的方法 1、Pointcut 切入点声明注解以及所有的通知注解都可以通过 value 属性或者 pointcut 属性指定切入点表达式。 2、切入点表达式通过 execution 函数匹配连接点语法execution([方法修饰符] 返回类型 包名.类名.方法名(参数类型) [异常类型]) 访问修饰符可以省略返回值类型、包名、类名、方法名可以使用星号*代表任意包名与类名之间一个点.代表当前包下的类两个点…表示当前包及其子包下的类;参数列表可以使用两个点…表示任意个数任意类型的参数列表; 3、切入点表达式的写法比较灵活比如* 号表示任意一个… 表示任意多个还可以使用 、||、! 进行逻辑运算不过实际开发中通常用不到那么多花里胡哨的掌握以下几种就基本够用了。 4、特别注意当明确指定了切入的类时类必须存在否则启动报错此时可以在类名前后加上*号表示模糊包含。 切入点表达式常用举例 标题内容execution(* com.wmx.aspect.EmpServiceImpl.findEmpById(Integer))匹配 com.wmx.aspect.EmpService 类中的 findEmpById 方法且带有一个 Integer 类型参数。execution(* com.wmx.aspect.EmpServiceImpl.findEmpById(*))匹配 com.wmx.aspect.EmpService 类中的 findEmpById 方法且带有一个任意类型参数。execution(* com.wmx.aspect.EmpServiceImpl.findEmpById(…))匹配 com.wmx.aspect.EmpService 类中的 findEmpById 方法参数不限。execution(* grp.basic3.se.service.SEBasAgencyService3.editAgencyInfo(…)) || execution(*grp.basic3.se.service.SEBasAgencyService3.adjustAgencyInfo(…))匹配 editAgencyInfo 方法或者 adjustAgencyInfo 方法Pointcut(“(execution(* grp.basic3…Controller.(…)) !execution( grp.basic3.BaseExceptionController*.*(…)))”)匹配 grp.basic3包及其子包下面名称包含 ‘Controller’ 类中的全部方法但是排除掉其中的以 BaseExceptionController 开头的类。execution(* com.wmx.aspect.EmpService.*(…))匹配 com.wmx.aspect.EmpService 类中的任意方法execution(* com.wmx.aspect..(…))匹配 com.wmx.aspect 包(不含子包)下任意类中的任意方法execution(* com.wmx.aspect….(…))匹配 com.wmx.aspect 包及其子包下任意类中的任意方法execution(* grp.pm…Controller.(…))匹配 grp.pm 包下任意子孙包中以 “Controller” 结尾的类中的所有方法* com.wmx…Controller.*(…))com.wmx 包及其子包下面类名包含’Controller’的任意类中的任意方法* com.wmx..controller..*(…))第一二层包名为 com.wmx 第三层包名任意第4层包名为 controller 下面的任意类中的任意方法 Pointcut(“annotation(xx)”) 拦截拥有指定注解的方法 /*** Pointcut 切入点声明即切入到哪些目标方法。* execution可以用于指定具体类中的具体方法* annotation匹配拥有指定注解的方法; 只匹配实现类中有注解的方法不会匹配接口中的注解方法; 如果注解是在类上,而不是方法上,并不会匹配类中的全部方法.* 用于被下面的通知注解引用这样通知注解只需要关联此切入点声明即可无需再重复写切入点表达式* annotation 中的路径表示拦截特定注解*/Pointcut(annotation(com.wmx.annotation.RedisLock))public void redisLockPC() {}环绕通知 实现开关目标方法 1、比如某个方法只有管理员才有权限执行而普通用户是没有权限 2、比如不符合条件的时候需要终止(跳过)目标方法的执行 3、比如一个组件(Component)专门用于做校验里面的方法是否校验可以配置在数据库中当配置为启用时则继续校验否则不校验。 /*** 环绕通知* 1、Around 的 value 属性绑定通知的切入点表达式。可以关联切入点声明也可以直接设置切入点表达式* 2、Object ProceedingJoinPoint.proceed(Object[] args) 方法继续下一个通知或目标方法调用返回处理结果如果目标方法发生异常则 proceed() 会抛异常.* 3、假如目标方法是控制层接口则本方法的异常捕获与否都不会影响业务层方法的事务回滚* 4、假如目标方法是控制层接口本方法 try-catch 了异常后没有继续往外抛则全局异常处理 RestControllerAdvice 中不会再触发*/Around(value aspectPointcut())public Object around(ProceedingJoinPoint joinPoint) throws Throwable {Signature signature joinPoint.getSignature();Object target joinPoint.getTarget();System.out.println(环绕通知 signature);System.out.println(环绕通知 target);// 是否继续校验boolean validation true;if (validation) {// 校验通过后执行目标方法// 继续下一个切面通知或目标方法调用返回处理结果如果目标方法发生异常则 proceed 会抛异常.// 如果在调用目标方法或者下一个切面通知前抛出异常则不会再继续往后走return joinPoint.proceed(joinPoint.getArgs());} else {// 校验未通过时不继续往后走直接返回。// 可以返回提示信息但是必须保证返回的参数类型与目标方法的返回值类型一致否则类型转换异常。// 也可以直接抛异常。return null;}}案例1自定义注解切面实现统一日志处理 1.自定义日志注解 /*** 自定义操作日志注解*/ Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) Documented public interface OptLog {/*** 业务* return*/String business();/*** 操作类型增删改查* return*/OptType optType(); }2声明日志切面组件 import com.alibaba.fastjson.JSONObject; import com.example.demo.annotation.OptLog; import com.example.demo.annotation.OptType; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.stereotype.Component; import java.lang.reflect.Method;Aspect Component public class OptLogAspect {private static final Logger LOG LoggerFactory.getLogger(OptLogAspect.class);/*** 声明切入点凡是使用该注解都经过拦截*/Pointcut(annotation(com.example.demo.annotation.OptLog))public void OptLog() {}Before(OptLog())public void doOptLogBefore(JoinPoint proceedingJoinPoint) {LOG.info(前置通知, 在方法执行之前执行...);}After(OptLog())public void doOptLogAfter(JoinPoint proceedingJoinPoint) {LOG.info(后置通知, 在方法执行之后执行...);}AfterReturning(OptLog())public void doOptLogAfterReturning(JoinPoint proceedingJoinPoint) {LOG.info(返回通知, 在方法返回结果之后执行...);}AfterThrowing(OptLog())public void doOptLogAfterThrowing(JoinPoint proceedingJoinPoint) {LOG.info(异常通知, 在方法抛出异常之后执行...);}/*** 设置环绕通知,围绕着方法执行** param proceedingJoinPoint* return*/Around(OptLog())public Object optLogAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {Method method ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();if (method null) {return null;}// 获取方法名称String methodName proceedingJoinPoint.getSignature().getName();LocalVariableTableParameterNameDiscoverer discoverer new LocalVariableTableParameterNameDiscoverer();// 请求参数名称String[] parameterNames discoverer.getParameterNames(method);// 请求参数值Object[] paramValues proceedingJoinPoint.getArgs();OptLog optLog method.getAnnotation(OptLog.class);this.handle(optLog.optType(), optLog.business(), methodName, parameterNames, paramValues);return proceedingJoinPoint.proceed();}/*** 日志处理** param optType* param business* param methodName* param parameterNames* param paramValues*/public void handle(OptType optType, String business, String methodName, String[] parameterNames, Object[] paramValues) {JSONObject jsonObject new JSONObject();if (parameterNames ! null parameterNames.length 0) {for (int i 0; i parameterNames.length; i) {jsonObject.put(parameterNames[i], paramValues[i]);}}LOG.info(optType: optType ,business: business , methodName: methodName , params: jsonObject);}}3.控制层运行结果 RestController RequestMapping(/user/) public class UserController {OptLog(optType OptType.CREATE,business 用户信息)RequestMapping(create)public String createUser(String userName,int age,String address) {System.out.println(方法执行中...);return success;} }4.运行结果 15:32:49.494 [http-nio-8080-exec-2] INFO c.e.d.a.OptLogAspect - [handle,91] - optType:CREATE,business:用户信息, methodName:createUser, params:{address:广州市,userName:阿杰,age:18} 15:32:49.494 [http-nio-8080-exec-2] INFO c.e.d.a.OptLogAspect - [doOptLogBefore,32] - 前置通知, 在方法执行之前执行... 方法执行中... 15:32:49.495 [http-nio-8080-exec-2] INFO c.e.d.a.OptLogAspect - [doOptLogAfterReturning,42] - 返回通知, 在方法返回结果之后执行... 15:32:49.495 [http-nio-8080-exec-2] INFO c.e.d.a.OptLogAspect - [doOptLogAfter,37] - 后置通知, 在方法执行之后执行...案例2自定义注解与切面类 1、创建自定义注解 import java.lang.annotation.*;Target({ ElementType.METHOD, ElementType.TYPE }) Retention(RetentionPolicy.RUNTIME) Documented public interface TestAnnotation {String name() default 默认值; // 允许注解有参数String age() default 15; // 允许多个参数 }2、创建一个类定义方法后使用自定义注解 import com.yh.annotation.OperateLogAnnotation; import com.yh.annotation.TestAnnotation; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; RestController RequestMapping(/test) public class TestAOPController {RequestMapping(/show3)ResponseBodyTestAnnotation(name 我把值传进去, age 24) // 加上自定义注解public String getById() { return hello;}}3、定义切面类进行扫描自定义注解并对切入点进行处理 import com.yh.annotation.TestAnnotation; import com.yh.annotation.TestAnnotation; //import javassist.bytecode.SignatureAttribute; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component;import java.lang.reflect.Method;Aspect // FOR AOP Order(-99) // 控制多个Aspect的执行顺序越小越先执行, 当然也可以不写这注解, 对于写和不写order的两个切面, 有order的优先于无order的执行; 都有order时, 越小越执先执行 Component public class TestAspect {// 可以参考若依的自定义注解。自定义注解一般使用annotation// Before可以有两种写法, annotation(形参test)Before(annotation(test))// 拦截被TestAnnotation注解的方法如果你需要拦截指定package指定规则名称的方法可以使用表达式execution(...)public void beforeTest(JoinPoint point, TestAnnotation test) throws Throwable {System.out.println(beforeTest: test.name()); // 直接获取注解参数//test.name()和test.age()}After(annotation(test))public void afterTest(JoinPoint point, TestAnnotation test) {System.out.println(afterTest: test.name()); // 直接获取注解参数}// 可以控制方法运行, 同时修改入参和返回值Around(annotation(test)) // test表示aroundTest方法中的test入参public Object aroundTest(ProceedingJoinPoint pjp, TestAnnotation test) throws Throwable {System.out.println(aroundTest: test.value());// 获取入参并修改Object[] args pjp.getArgs();args[0] ;// 传入修改后的参数, 并继续执行Object res pjp.proceed(args);// 修改返回值return res.toString() res.toString();}/* // 指定切面Pointcut(annotation(com.yh.annotation.TestAnnotation))public void annotationPointCut() {}// Before可以有两者写法, annotation(函数名annotationPointCut)Before(annotationPointCut())public void before(JoinPoint joinPoint) {MethodSignature sign (MethodSignature) joinPoint.getSignature();Method method sign.getMethod();TestAnnotation annotation method.getAnnotation(TestAnnotation.class); // 获取指定注解实例System.out.println(打印 annotation.name() 前置日志1); // 获取注解实例的参数}After(annotationPointCut())public void afterTTT(JoinPoint point) {MethodSignature sign (MethodSignature) point.getSignature();Method method sign.getMethod();TestAnnotation annotation method.getAnnotation(TestAnnotation.class); // 获取指定注解实例System.out.println(打印自带参数 annotation.age() 后置日志1); // 获取注解实例的参数} */}

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

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

相关文章

怎样搜网站网页图片下载不了怎么办

目录 一、扩展和收缩 二、使用高质量的哈希函数 三、使用跳跃表(skiplist)或其他数据结构 四、哈希表分片 一、扩展和收缩 Redis通过动态调整哈希表的大小来解决“数组链表”的长度问题,这涉及到两个过程:扩展(Expand)和收缩(S…

国内优秀网站案例自己做网站需要主机吗

11月20日,群核科技在杭州举办了第九届酷科技峰会。现场,群核科技首次正式介绍其技术底层核心:基于GPU高性能计算的物理世界模拟器。并对外公开了两大技术引擎:群核启真(渲染)引擎和群核矩阵(CAD…

网站横幅背景图片建设一个官方网站多少钱

一般3年左右经验的程序员,了解到了这个行业的一些上升渠道和方法,其实也能发现,程序员也能得熬资历的,说通俗点也是越老越值钱。 比如当下有1年经验和3年经验的程序员,哪怕都是小公司背景,会发现工作年限越…

为什么要做网站优化建站平台免代码

看这个网址:讲的很详细,后面补实战例子 第一章 - MQTT介绍 MQTT协议中文版 (gitbooks.io)https://mcxiaoke.gitbooks.io/mqtt-cn/content/mqtt/01-Introduction.html

html5 3d网站wordpress适应浏

最近一直在整理单目测距的内容,想着检测单目测距都写完了,顺手也写个检测跟踪单目测距,算是总结下这部分内容吧,如果有错误,还请不吝赐教!! 参考文献: YOLOv5DeepSort实现目标跟踪 pytorch yolo…

做网站需要什么证明嘛wordpress一键脚本

世界第一家 VR 影院已经开张,朋友,去不? 世界第一家 VR 影院正式开张 (无大屏的 VR 电影院) 在被称为 VR 元年的 2016 年,越来越多的人加入了这个新兴的领域,各种传统应用也在被 VR 包装之后以…

wordpress用户站点网络营销是什么 能做什么

共用体 共用体 union 共用体名 { 成员列表; };//表示定义一个共用体类型 注意: 1.共用体 初始化 --- 只能给一个值,默认是给到第一个成员变量 2.共用体成员变量辅助 3.可以判断大小端 ----※!! 实际用途…

orchard可以做哪些网站wap是什么意思

第13套: 给定程序中,函数fun的功能是将带头节点的单向链表结点数据域中的数据从小到大排序。即若原链表结点数据域从头至尾的数据为:10、4、2、8、6,排序 后链表结点数据域从头至尾的数据为:2、4、6、8、10。 请在程序的下划线处填…

做航空产品的网站有哪些重庆镇海seo整站优化价格

文章目录 参考文章环境背景1、配置打包好的程序1.1、下载GeoServer的war包1.2、下载GeoWebCache1.3、拷贝jar包1.4、修改配置文件1.4.1、拷贝geowebcache-arcgiscache-context.xml1.4.2、修改geowebcache-core-context.xml1.4.3、修改geowebcache-servlet.xml 1.5、配置切片信息…

dede网站版权信息修改推广代运营公司

1.微信小程序,设置src/app.json 中的tabBar 图标选择来自 iconfont 如图所示 小程序显示如下: 转载于:https://www.cnblogs.com/0909/p/11144861.html

织梦网站定制网站建设如何找本地客户

NB水表,作为新一代智能水表,以小巧的体积、稳定的性能和强大的功能赢得了市场的认可。那么,它究竟能承受多大的水压呢?接下来,小编来为大家揭秘下,一起来看下吧! 一、NB水表概述 NB水表&#xf…

做网站要租服务器吗购物网站产品做促销能赚钱吗

计算机应用基础课程辅助教学及智能测评系统使用手册(网络版)一、服务器端安装硬件要求如下:系统需求客户机CPU建议 Pentium m 800 MHz 以上内存512 MB以上系统要求Windows XP SP3IBS(IE7) Office2007具体安装步骤如下:文件,出现如下画面,选择…

wordpress4.9+多站点黄金网站app免费视频下载

一、初识C语言 C语言诞生于美国的贝尔实验室,由丹尼斯里奇(Dennis MacAlistair Ritchie)以肯尼斯蓝汤普森(Kenneth Lane Thompson)设计的B语言为基础发展而来,C语言是一个功能简化的版本,它使C…

最牛餐饮营销手段seo网站权重

最近在做华为机试体验题,遇到一个“找零钱”的题目,如下 想起之前在牛客网上看到左程云老师讲过的动态规划问题,很像,题目如下: 有数组penny,penny中所有的值都为正数且不重复。每个值代表一种面值的货币&…

用毛做简单的网站iis网站筛选器被挂马

Python是一种高级编程语言,具有简单易学、代码可读性强、开发效率高等特点。它采用解释型执行方式,可以跨平台运行,并且拥有丰富的第三方库和框架支持,被广泛应用于Web开发、数据分析、人工智能等领域。 文章目录 一、Python的历…

深圳市空间设计有限公司如何优化推广网站

我们的项目中几乎都会有配置文件,里面可能会存储一些敏感信息,比如数据库连接字符串、第三方API的AppKey和SecretKey等。对于开源项目,这些敏感信息肯定不能随着源代码一起提交到托管平台。对于网站应用大多都是要部署到有公开IP的服务器上的…

400电话实名制认证网站百度信息流投放方式有哪些

文章目录 chart包应用环境一、安装helm客户端工具二、chart包目录结构三、创建不可配置的chart1.创建目录和chart.yaml2.创建deployment.yaml3.创建service.yaml4.使用chart安装应用5.查看和验证 四、创建可配置的Chart1.官方的预定义变量2.新增values.yaml文件3.配置deploy引用…

做学分网站公司做网站百度还是阿里

喜欢就关注我们吧!TIOBE 已公布 2020 年 9 月的编程语言排行榜。C 近期发展状态不错,依旧在榜单中排第四,但排名比率保持增长,本月为 7.11%。2003 年是 C 的巅峰时期,当年 8 月,它的 TIOBE 排名峰值为 17.5…

wordpress文章添加seo标题商丘市网络优化公司地址

前言: 本章我们就来了解Java中的反射和枚举类。枚举类和反射其实有些关系,接下来我们就来学习他们的使用。 反射: 反射的作用: 反射:反射允许对成员变量,成员方法和构造方法的信息进行编程访问。 Java中有…

关于建设网站的合作合同范本商会网站建设

第 7 章 并行与并发 文章目录第 7 章 并行与并发7.1 并行基础7.2 互斥量与临界区7.3 期物7.4 条件变量7.5 原子操作与内存模型原子操作一致性模型内存顺序总结习题进一步阅读的参考资料7.1 并行基础 std::thread 用于创建一个执行的线程实例,所以它是一切并发编程的…