优雅的接口防刷处理方案

大家好,我是老赵!

本文为描述通过Interceptor以及Redis实现接口访问防刷Demo

这里会通过逐步找问题,逐步去完善的形式展示

原理

  • 通过ip地址+uri拼接用以作为访问者访问接口区分

  • 通过在Interceptor中拦截请求,从Redis中统计用户访问接口次数从而达到接口防刷目的

如下图所示

35c8badaba90490cc725a53ccd6bc797.png

工程

项目地址:

https://github.com/Tonciy/interface-brush-protection

Apifox地址:Apifox 密码:Lyh3j2Rv

其中,Interceptor处代码处理逻辑最为重要

43bbcba91fe3a43e29f1fc6e6a96c63b.png
@Slf4j
public class AccessLimintInterceptor  implements HandlerInterceptor {@Resourceprivate RedisTemplate<String, Object> redisTemplate;/*** 多长时间内*/@Value("${interfaceAccess.second}")private Long second = 10L;/*** 访问次数*/@Value("${interfaceAccess.time}")private Long time = 3L;/*** 禁用时长--单位/秒*/@Value("${interfaceAccess.lockTime}")private Long lockTime = 60L;/*** 锁住时的key前缀*/public static final String LOCK_PREFIX = "LOCK";/*** 统计次数时的key前缀*/public static final String COUNT_PREFIX = "COUNT";public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String uri = request.getRequestURI();String ip = request.getRemoteAddr(); // 这里忽略代理软件方式访问,默认直接访问,也就是获取得到的就是访问者真实ip地址String lockKey = LOCK_PREFIX + ip + uri;Object isLock = redisTemplate.opsForValue().get(lockKey);if(Objects.isNull(isLock)){// 还未被禁用String countKey = COUNT_PREFIX + ip + uri;Object count = redisTemplate.opsForValue().get(countKey);if(Objects.isNull(count)){// 首次访问log.info("首次访问");redisTemplate.opsForValue().set(countKey,1,second, TimeUnit.SECONDS);}else{// 此用户前一点时间就访问过该接口if((Integer)count < time){// 放行,访问次数 + 1redisTemplate.opsForValue().increment(countKey);}else{log.info("{}禁用访问{}",ip, uri);// 禁用redisTemplate.opsForValue().set(lockKey, 1,lockTime, TimeUnit.SECONDS);// 删除统计redisTemplate.delete(countKey);throw new CommonException(ResultCode.ACCESS_FREQUENT);}}}else{// 此用户访问此接口已被禁用throw new CommonException(ResultCode.ACCESS_FREQUENT);}return true;}
}

在多长时间内访问接口多少次,以及禁用的时长,则是通过与配置文件配合动态设置

e4c5dc93550acca93221c10276819c4a.png

当处于禁用时直接抛异常则是通过在ControllerAdvice处统一处理 (这里代码写的有点丑陋)

77f562d88fa95127857fe9a9a6756987.png

下面是一些测试(可以把项目通过Git还原到“【初始化】”状态进行测试)

  • 正常访问时

bc338833bd7e521a28649f1003d2b307.png dda0d3dd1c1a7a1c44cb250ee8fb1c27.png
  • 访问次数过于频繁时

1fe2805f6725f7d98c05bed13fe4197a.png ec01bd3b593f5b8b15153548213ec89d.png

自我提问

上述实现就好像就已经达到了我们的接口防刷目的了

但是,还不够

为方便后续描述,项目中新增补充Controller,如下所示

e568c33678adeff2825e0603b242c0ae.png

简单来说就是

  • PassCotrollerRefuseController

  • 每个Controller分别有对应的get,post,put,delete类型的方法,其映射路径与方法名称一致

接口自由

  • 对于上述实现,不知道你们有没有发现一个问题

  • 就是现在我们的接口防刷处理,针对是所有的接口(项目案例中我只是写的接口比较少)

  • 而在实际开发中,说对于所有的接口都要做防刷处理,感觉上也不太可能(写此文时目前大四,实际工作经验较少,这里不敢肯定)

  • 那么问题有了,该如何解决呢?目前来说想到两个解决方案

拦截器映射规则

项目通过Git还原到"【Interceptor设置映射规则实现接口自由】"版本即可得到此案例实现

我们都知道拦截器是可以设置拦截规则的,从而达到拦截处理目的

5ab0480a04e709603c64d22936a80565.png

1.这个AccessInterfaceInterceptor是专门用来进行防刷处理的,那么实际上我们可以通过设置它的映射规则去匹配需要进行【接口防刷】的接口即可

2.比如说下面的映射配置

716beffb3ee8afd4947bcc3ede1d6328.png

3.这样就初步达到了我们的目的,通过映射规则的配置,只针对那些需要进行【接口防刷】的接口才会进行处理

4.至于为啥说是初步呢?下面我就说说目前我想到的使用这种方式进行【接口防刷】的不足点:

所有要进行防刷处理的接口统一都是配置成了 x 秒内 y 次访问次数,禁用时长为 z 秒

  • 要知道就是要进行防刷处理的接口,其 x, y, z的值也是并不一定会统一的

  • 某些防刷接口处理比较消耗性能的,我就把x, y, z设置的紧一点

  • 而某些防刷接口处理相对来说比较快,我就把x, y, z 设置的松一点

  • 这没问题吧

  • 但是现在呢?x, y, z值全都一致了,这就不行了

  • 这就是其中一个不足点

  • 当然,其实针对当前这种情况也有解决方案

  • 那就是弄多个拦截器

  • 每个拦截器的【接口防刷】处理逻辑跟上述一致,并去映射对应要处理的防刷接口

  • 唯一不同的就是在每个拦截器内部,去修改对应防刷接口需要的x, y, z值

  • 这样就是感觉会比较麻烦

防刷接口映射路径修改后维护问题

  • 虽然说防刷接口的映射路径基本上定下来后就不会改变

  • 但实际上前后端联调开发项目时,不会有那么严谨的Api文档给我们用(这个在实习中倒是碰到过,公司不是很大,开发起来也就不那么严谨,啥都要自己搞,功能能实现就好)

  • 也就是说还是会有那种要修改接口的映射路径需求

  • 当防刷接口数量特别多,后面的接手人员就很痛苦了

  • 就算是项目是自己从0到1实现的,其实有时候项目开发到后面,自己也会忘记自己前面是如何设计的

  • 而使用当前这种方式的话,谁维护谁蛋疼

自定义注解 + 反射

咋说呢

  • 就是通过自定义注解中定义 x 秒内 y 次访问次数,禁用时长为 z 秒

  • 自定义注解 + 在需要进行防刷处理的各个接口方法上

  • 在拦截器中通过反射获取到各个接口中的x, y, z值即可达到我们想要的接口自由目的

下面做个实现

声明自定义注解

7bedc9bda4cdb20ab9f65fcbb0015dd2.png

Controlller中方法中使用

37cee9a632806d2973008e9774f8e28c.png

Interceptor处逻辑修改(最重要是通过反射判断此接口是否需要进行防刷处理,以及获取到x, y, z的值)

@Slf4j
public class AccessLimintInterceptor  implements HandlerInterceptor {@Resourceprivate RedisTemplate<String, Object> redisTemplate;/*** 锁住时的key前缀*/public static final String LOCK_PREFIX = "LOCK";/*** 统计次数时的key前缀*/public static final String COUNT_PREFIX = "COUNT";public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//        自定义注解 + 反射 实现// 判断访问的是否是接口方法if(handler instanceof HandlerMethod){// 访问的是接口方法,转化为待访问的目标方法对象HandlerMethod targetMethod = (HandlerMethod) handler;// 取出目标方法中的 AccessLimit 注解AccessLimit accessLimit = targetMethod.getMethodAnnotation(AccessLimit.class);// 判断此方法接口是否要进行防刷处理(方法上没有对应注解就代表不需要,不需要的话进行放行)if(!Objects.isNull(accessLimit)){// 需要进行防刷处理,接下来是处理逻辑String ip = request.getRemoteAddr();String uri = request.getRequestURI();String lockKey = LOCK_PREFIX + ip + uri;Object isLock = redisTemplate.opsForValue().get(lockKey);// 判断此ip用户访问此接口是否已经被禁用if (Objects.isNull(isLock)) {// 还未被禁用String countKey = COUNT_PREFIX + ip + uri;Object count = redisTemplate.opsForValue().get(countKey);long second = accessLimit.second();long maxTime = accessLimit.maxTime();if (Objects.isNull(count)) {// 首次访问log.info("首次访问");redisTemplate.opsForValue().set(countKey, 1, second, TimeUnit.SECONDS);} else {// 此用户前一点时间就访问过该接口,且频率没超过设置if ((Integer) count < maxTime) {redisTemplate.opsForValue().increment(countKey);} else {log.info("{}禁用访问{}", ip, uri);long forbiddenTime = accessLimit.forbiddenTime();// 禁用redisTemplate.opsForValue().set(lockKey, 1, forbiddenTime, TimeUnit.SECONDS);// 删除统计--已经禁用了就没必要存在了redisTemplate.delete(countKey);throw new CommonException(ResultCode.ACCESS_FREQUENT);}}} else {// 此用户访问此接口已被禁用throw new CommonException(ResultCode.ACCESS_FREQUENT);}}}return  true;}
}

由于不好演示效果,这里就不贴测试结果图片了

项目通过Git还原到"【自定义主键+反射实现接口自由"版本即可得到此案例实现,后面自己可以针对接口做下测试看看是否如同我所说的那样实现自定义x, y, z 的效果

嗯,现在看起来,可以针对每个要进行防刷处理的接口进行针对性自定义多长时间内的最大访问次数,以及禁用时长,哪个接口需要,就直接+在那个接口方法出即可

感觉还不错的样子,现在网上挺多资料也都是这样实现的

但是还是可以有改善的地方

先举一个例子,以我们的PassController为例,如下是其实现

585cfa055743b335a3a15c07e502e893.png

下图是其映射路径关系

14e192286d57a4d7d0095e1f216d4519.png

同一个Controller的所有接口方法映射路径的前缀都包含了/pass

我们在类上通过注解@ReqeustMapping标记映射路径/pass,这样所有的接口方法前缀都包含了/pass,并且以致于后面要修改映射路径前缀时只需改这一块地方即可

这也是我们使用SpringMVC最常见的用法

那么,我们的自定义注解也可不可以这样做呢?先无中生有个需求

假设PassController中所有接口都是要进行防刷处理的,并且他们的x, y, z值就一样

如果我们的自定义注解还是只能加载方法上的话,一个一个接口加,那么无疑这是一种很呆的做法

要改的话,其实也很简单,首先是修改自定义注解,让其可以作用在类上

23ca29346b4fe3a10859c709c7da64ea.png

接着就是修改AccessLimitInterceptor的处理逻辑

AccessLimitInterceptor中代码修改的有点多,主要逻辑如下

cc7dc34d0693ca930342d4ad760ca5dc.png

与之前实现比较,不同点在于x, y, z的值要首先尝试在目标类中获取

其次,一旦类中标有此注解,即代表此类下所有接口方法都要进行防刷处理

如果其接口方法同样也标有此注解,根据就近优先原则,以接口方法中的注解标明的值为准

@Slf4j
public class AccessLimintInterceptor implements HandlerInterceptor {@Resourceprivate RedisTemplate<String, Object> redisTemplate;/*** 锁住时的key前缀*/public static final String LOCK_PREFIX = "LOCK";/*** 统计次数时的key前缀*/public static final String COUNT_PREFIX = "COUNT";public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//      自定义注解 + 反射 实现, 版本 2.0if (handler instanceof HandlerMethod) {// 访问的是接口方法,转化为待访问的目标方法对象HandlerMethod targetMethod = (HandlerMethod) handler;// 获取目标接口方法所在类的注解@AccessLimitAccessLimit targetClassAnnotation = targetMethod.getMethod().getDeclaringClass().getAnnotation(AccessLimit.class);// 特别注意不能采用下面这条语句来获取,因为 Spring 采用的代理方式来代理目标方法//  也就是说targetMethod.getClass()获得是class org.springframework.web.method.HandlerMethod ,而不知我们真正想要的 Controller//            AccessLimit targetClassAnnotation = targetMethod.getClass().getAnnotation(AccessLimit.class);// 定义标记位,标记此类是否加了@AccessLimit注解boolean isBrushForAllInterface = false;String ip = request.getRemoteAddr();String uri = request.getRequestURI();long second = 0L;long maxTime = 0L;long forbiddenTime = 0L;if (!Objects.isNull(targetClassAnnotation)) {log.info("目标接口方法所在类上有@AccessLimit注解");isBrushForAllInterface = true;second = targetClassAnnotation.second();maxTime = targetClassAnnotation.maxTime();forbiddenTime = targetClassAnnotation.forbiddenTime();}// 取出目标方法中的 AccessLimit 注解AccessLimit accessLimit = targetMethod.getMethodAnnotation(AccessLimit.class);// 判断此方法接口是否要进行防刷处理if (!Objects.isNull(accessLimit)) {// 需要进行防刷处理,接下来是处理逻辑second = accessLimit.second();maxTime = accessLimit.maxTime();forbiddenTime = accessLimit.forbiddenTime();if (isForbindden(second, maxTime, forbiddenTime, ip, uri)) {throw new CommonException(ResultCode.ACCESS_FREQUENT);}} else {// 目标接口方法处无@AccessLimit注解,但还要看看其类上是否加了(类上有加,代表针对此类下所有接口方法都要进行防刷处理)if (isBrushForAllInterface && isForbindden(second, maxTime, forbiddenTime, ip, uri)) {throw new CommonException(ResultCode.ACCESS_FREQUENT);}}}return true;}/*** 判断某用户访问某接口是否已经被禁用/是否需要禁用** @param second        多长时间  单位/秒* @param maxTime       最大访问次数* @param forbiddenTime 禁用时长 单位/秒* @param ip            访问者ip地址* @param uri           访问的uri* @return ture为需要禁用*/private boolean isForbindden(long second, long maxTime, long forbiddenTime, String ip, String uri) {String lockKey = LOCK_PREFIX + ip + uri; //如果此ip访问此uri被禁用时的存在Redis中的 keyObject isLock = redisTemplate.opsForValue().get(lockKey);// 判断此ip用户访问此接口是否已经被禁用if (Objects.isNull(isLock)) {// 还未被禁用String countKey = COUNT_PREFIX + ip + uri;Object count = redisTemplate.opsForValue().get(countKey);if (Objects.isNull(count)) {// 首次访问log.info("首次访问");redisTemplate.opsForValue().set(countKey, 1, second, TimeUnit.SECONDS);} else {// 此用户前一点时间就访问过该接口,且频率没超过设置if ((Integer) count < maxTime) {redisTemplate.opsForValue().increment(countKey);} else {log.info("{}禁用访问{}", ip, uri);// 禁用redisTemplate.opsForValue().set(lockKey, 1, forbiddenTime, TimeUnit.SECONDS);// 删除统计--已经禁用了就没必要存在了redisTemplate.delete(countKey);return true;}}} else {// 此用户访问此接口已被禁用return true;}return false;}
}

好了,这样就达到我们想要的效果了

c6b5de01ccb0395340ced2be519131d2.png

项目通过Git还原到"【自定义注解+反射实现接口自由-版本2.0】"版本即可得到此案例实现,自己可以测试万一下

这是目前来说比较理想的做法,至于其他做法,暂时没啥了解到

时间逻辑漏洞

这是我一开始都有留意到的问题

也是一直搞不懂,就是我们现在的所有做法其实感觉都不是严格意义上的x秒内y次访问次数

特别注意这个x秒,它是连续,任意的(代表这个x秒时间片段其实是可以发生在任意一个时间轴上)

我下面尝试表达我的意思,但是我不知道能不能表达清楚

假设我们固定某个接口5秒内只能访问3次,以下面例子为例

2f9145c38e98f9ef9941127d1c7c6d98.png

底下的小圆圈代表此刻请求访问接口

按照我们之前所有做法的逻辑走

  1. 第2秒请求到,为首次访问,Redis中统计次数为1(过期时间为5秒)

  2. 第7秒,此时有两个动作,一是请求到,二是刚刚第二秒Redis存的值现在过期

  3. 我们先假设这一刻,请求处理完后,Redis存的值才过期

  4. 按照这样的逻辑走

  5. 第七秒请求到,Redis存在对应key,且不大于3, 次数+1

  6. 接着这个key立马过期

  7. 再继续往后走,第8秒又当做新的一个起始,就不往下说了,反正就是不会出现禁用的情况

按照上述逻辑走,实际上也就是说当出现首次访问时,当做这5秒时间片段的起始

第2秒是,第8秒也是

但是有没有想过,实际上这个5秒时间片段实际上是可以放置在时间轴上任意区域的

上述情况我们是根据请求的到来情况人为的把它放在【2-7】,【8-13】上

而实际上这5秒时间片段是可以放在任意区域的

那么,这样的话,【7-12】也可以放置

而【7-12】这段时间有4次请求,就达到了我们禁用的条件了

是不是感觉怪怪的

想过其他做法,但是好像严格意义上真的做不到我所说的那样(至少目前来说想不到)

之前我们的做法,正常来说也够用,至少说有达到防刷的作用

后面有机会的话再看看,不知道我是不是钻牛角尖了

路径参数问题

假设现在PassController中有如下接口方法

f3933835a0a448e72c2a363ef52abadf.png

也就是我们在接口方法中常用的在请求路径中获取参数的套路

但是使用路径参数的话,就会发生问题

那就是同一个ip地址访问此接口时,我携带的参数值不同

按照我们之前那种前缀+ip+uri拼接的形式作为key的话,其实是区分不了的

下图是访问此接口,携带不同参数值时获取的uri状况

4852f9c63443e8bb1de89c7f2714f1af.png

这样的话在我们之前拦截器的处理逻辑中,会认为是此ip用户访问的是不同的接口方法,而实际上访问的是同一个接口方法

也就导致了【接口防刷】失效

接下来就是解决它,目前来说有两种

不要使用路径参数

这算是比较理想的做法,相当于没这个问题

但有一定局限性,有时候接手别的项目,或者自己根本没这个权限说不能使用路径参数

替换uri

  • 我们获取uri的目的,其实就是为了区别访问接口

  • 而把uri替换成另一种可以区分访问接口方法的标识即可

  • 最容易想到的就是通过反射获取到接口方法名称,使用接口方法名称替换成uri即可

  • 当然,其实不同的Controller中,其接口方法名称也有可能是相同的

  • 实际上可以再获取接口方法所在类类名,使用类名 + 方法名称替换uri即可

  • 实际解决方案有很多,看个人需求吧

真实ip获取

在之前的代码中,我们获取代码都是通过request.getRemoteAddr()获取的

但是后续有了解到,如果说通过代理软件方式访问的话,这样是获取不到来访者的真实ip的

至于如何获取,后续我再研究下http再说,这里先提个醒

总结

说实话,挺有意思的,一开始自己想【接口防刷】的时候,感觉也就是转化成统计下访问次数的问题摆了。后面到网上看别人的写法,又再自己给自己找点问题出来,后面会衍生出来一推东西出来,诸如自定义注解+反射这种实现方式。

以前其实对注解 + 反射其实有点不太懂干嘛用的,而从之前的数据报表导出,再到基本权限控制实现,最后到今天的【接口防刷】一点点来进步去补充自己的知识点,而且,感觉写博客真的是件挺有意义的事情,它会让你去更深入的了解某个点,并且知识是相关联的,探索的过程中会牵扯到其他别的知识点,就像之前的写的【单例模式】实现,一开始就了解到懒汉式,饿汉式

后面深入的话就知道其实会还有序列化/反序列化,反射调用生成实例,对象克隆这几种方式回去破坏单例模式,又是如何解决的,这也是一个进步的点,后续为了保证线程安全问题,牵扯到的synchronized,voliate关键字,继而又关联到JVM,JUC,操作系统的东西。

来源:juejin.cn/post/7200366809407750181

最近一段时间,ChatGPT技术爆火了!炮哥搞了个ChatGPT实战星球给大家学习,避免大家到处找资料,浪费时间,欢迎加入。

18360cf8d2977ce76d1c03b02c6beeab.png

专栏以实战搞钱为主,内容在快马加鞭的每天更新,目前核心内容如下,全是自己原创干货,没有任何水分,加入保证不后悔。

d5a3871e11dc4fb62c7e876bc2748bb6.png

我通过1个半月对ChatGPT的学习,ChatGPT真的太强大了,太好用了,很多人都起飞了。控制不住自己,我也终于入局了把最近一个月整理的干货、经验、ChatGPT实战案例、搞钱技巧分享给大家承诺每天持续更新

朋友圈也经常有人找我咨询 ChatGPT,根本回答不过来,于是我创建了一个《ChatGPT掘金俱乐部》知识星球,和大家分享这个巨大的红利。加入知识星球 一起掘金了!

加入后3大福利:

1.前50名送ChatGPT独立账号

加入即送一个超难注册的 ChatGPT 账号,个人独享,官方纯手动注册,安全可靠,以及带你搭建ChatGPT服务。
光一个账号就值几十块,星球还输出了 30+ 篇干货,持续更新中,早已值回票价:

2.前30名送纸质实体书(包邮)

另外前30名加入可获得一本纸质实体书(包邮)可选书有:《淘宝交付之道》、《ElasticSearch数据搜索与分析实战》、《零基础血Web3.0》、《分布式系统架构与开发:技术原理与面试题解析》、《Java多线程编程核心技术(第3版)》、《Java核心技术 卷I:开发基础(原书第12版)》.....等十几本好书。

3.本星球特色:

1.主打ChatGPT实战案例和项目,星球内准备了大量的实战项目(持续输出),你可以学到如下:

  • ChatGPT+Midjourney实战

  • ChatGPT生成PPT

  • ChatGPT生成代码

  • ChatGPT辅助生成文章

  • ChatGPT合成视频/音频

  • ChatGPT辅助生成周报

  • ChatGPT辅助小红书小作文生成

  • ..........

2.程序员如何使用ChatGPT提高开发效率,你可以学到如下:

  • 帮你生成完整 Github README

  • shell 中使用 ChatGPT

  • 搭建属于自己的 ChatGPT 网站

  • 智能测试:codium

  • 通过聊天生成 SQL 操作数据库

  • 自动代码编辑器: Cursor

  • 开发自己的 ChatGPT 应用

  • ...........

4.本星球整理了目前市面上最全的资料,免费学习(持续更新)

9d5a9a6039d8a5dca6bb8d673ee238d2.png

18318f89090e5560ff0ed33f828817a7.png

今天送个大家几张优惠卷,用下面的扫码有优惠券,先到先得!

59789f68709e4d4a5ca6e9c58b3907d6.png

最后,有问题咨询或者想加入ChatGPT社群一起抱团取暖的欢迎添加我的微信。

8f138bcae352ee613605bcea6c87a5e0.png

欢迎加入星球,一起抱团取暖!

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

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

相关文章

生成式AI发现潜在抗癌药物;王慧文与“一流科技”达成并购意向;阿里巴巴公布六大业务集团CEO丨每日大事件...

‍ ‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 企业动态 阿里巴巴公布六大业务集团CEO&#xff1a;张勇兼任阿里云智能集团CEO 3月28日&#xff0c;阿里巴巴集团董事会主席兼首席执行官张勇发布全员信&#xff0c;宣布启动“16N”组织变革。根据全员信&#xff0c;张勇…

感谢十二年的陪伴——分享回归,不忘初心(Eastmount博客总结及未来规划)

曾记否&#xff0c;2021年4月28日&#xff0c;为了更好地从事科研和学习&#xff0c;当时给所有读者群发了我在CSDN唯一的私信&#xff0c;感谢大家十年的陪伴&#xff0c;短暂消失&#xff0c;不负青春。当时也收到了很多博友的鼓励与祝福&#xff0c;感恩。 是啊&#xff01…

爆火的 Auto-GPT 被过分吹捧了!

整理 | 王子彧 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; Jina AI 的创始人兼 CEO 肖涵发布的《揭秘 Auto-GPT 喧嚣背后的残酷真相&#xff01;》一文中&#xff0c;肖涵博士表示道&#xff1a;想要在现实的生产环境中使用 Auto-GPT&#xff0c;首先面临的障…

雷军:小米汽车争取15-20年进入世界前五;GitHub宣布裁员10%,全员转远程办公;谷歌AR/VR负责人宣布离职|极客头条...

「极客头条」—— 技术人员的新闻圈&#xff01; CSDN 的读者朋友们早上好哇&#xff0c;「极客头条」来啦&#xff0c;快来看今天都有哪些值得我们技术人关注的重要新闻吧。 整理 | 梦依丹 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 一分钟速览新闻点&#…

快来!Claude无需魔法不限量;百度官方AIGC公开课;Prompt高质量答案完全指南;GPT-5真的要来了?贾扬清离职阿里后首次受访 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 『3月AI大事记&干货集』4月国内互联网持续发力中&#xff0c;精彩精彩 &#x1f916; 『GPT-4.5/GPT-5真的要来了&#xff1f;』怎…

一文讲透产品经理如何用好ChatGPT

作者&#xff1a;京东零售 何雨航 “4.0版本的ChatGPT可以有效提升产品经理工作效率&#xff0c;但并无法替代产品经理的角色。” 一、引言 3月15日&#xff0c;OpenAI发布了最新的基于GPT-4的ChatGPT&#xff0c;关于其智能性的讨论热度在互联网上空前高涨。 我之前体验过3…

【产业互联网周报】微软Bing搜索全面开放ChatGPT;阿里云回应工商变更;科大讯飞发布星火大模型...

关注ITValue&#xff0c;看企业级最新鲜、最价值报道&#xff01; 拜登会见人工智能公司CEO&#xff0c;并亲自使用了ChatGPT&#xff1b;白宫宣布首个AI监管计划&#xff1a;拨款1.4亿美元研究&#xff0c;制定指导方针&#xff1b;讯飞星火算力硬件主要由华为提供&#xff0c…

AI人工智能大模型失守!ChatGPT、BARD、BING、Claude 相继被提示攻击攻陷!

“ 提示攻击&#xff0c;一种利用巧妙的技巧和迷惑性的指令&#xff0c;让这些顶尖的语言模型产生混乱或错误的回答的方法。” 01 — 什么是提示攻击‍‍ 之前在文章&#xff1a;已证实&#xff1a;GPT不能提供有效的Windows11的密钥 提到&#xff0c;有人曾利用让 ChatGPT 扮演…

谷歌AI聊天机器人Bard答错问题,股价大跌7.4%;淘宝屏蔽ChatGPT;孟晚舟4月将首次当值华为轮值董事长丨每日大事件...

‍ ‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 投融资‍‍ 深氧科技获千万元级天使轮融资 3D短视频的一站式AIGC引擎技术服务提供商深氧科技于2月8日宣布完成由汉能创投投资的千万元级天使轮融资。本次融资用于产品迭代及技术团队扩充。 深氧科技成立于2022年&#xf…

李想两万字回应:我们如何造车?

来源&#xff1a;汽车电子与软件 3月2日举办的特斯拉投资者日&#xff0c;投资者们不太开心。股东们都期望着特斯拉解决眼前市场需求不足的急迫问题&#xff0c;但马斯克只想用清洁能源拯救地球——斥资10万亿美元&#xff0c;还要全世界团结在一起。 如果不是他已经带领特斯拉…

Django项目中的问题

文章目录 文章目录 文章目录nginx uwsgi django如何实现第三方认证多人联机对战使用Trift服务实现匹配模块mq 基础知识为什么需要mqmq的使用场景消息队列优点mq的问题消息队列中的topic 做项目时遇到的难点redis和mysql1.redis的基本知识redis的数据结构持久化AOF日志RDB快照…

你说你还不会Redis?别怕,今天带你搞定它!

Redis 前言 本文章是我学习过程中&#xff0c;不断总结而成&#xff0c;篇幅较长&#xff0c;可以根据选段阅读。 全篇17000字&#xff0c;图片 十三 张&#xff0c;预计用时1小时。 认识Redis 什么是Redis&#xff1f; 要使用一门技术&#xff0c;首先要知道这门技术是什…

学习Vue这一个就够

1、淘宝镜像 1: 解释一下 npm 为什么要配置淘宝镜像原因&#xff1a;因为node.js 默认使用的是国外的网站 。国内访问有一个跨国内局域网的操作。所以就会有时候很慢。这就跟为什么网站的静态资源有些会使用CDN 加速一样的淘宝镜像是什么&#xff1f;就是npm 很多的插件淘宝已经…

【coderwhy前端笔记 - 阶段六 VUE 】(整理版)(更新中2023.7.16)

coderwhy前端系统课 - 阶段六VUE (整理版)&#xff08;更新中2023.7.16&#xff09; 1. 前言 本文以coderwhy前端系统课 - 阶段六VUE为主。 一刷版本的笔记有些乱&#xff0c;目前还在二刷整理&#xff0c;同时参考了一部分其他的资料&#xff0c;并加上个人使用总结 建议使…

小红书内容传播之品牌推广,干货分析

对于一个品牌来说&#xff0c;想要做好信息传播&#xff0c;迅速抢占市场&#xff0c;找准战场非常重要。而小红书&#xff0c;很显然就是时下众多品牌&#xff0c;竞相进驻的平台。那么如何在小红书平台做好品牌推广呢&#xff0c;今天为大家解读下。 一、做好品牌推广的三大步…

小程序 分享卡片 禁止个人及群聊二次转发

遇到开发需求说&#xff0c;分享消息给好友及群聊&#xff0c;但不允许二次转发 查了好多资料 最后很简单的解决了 就是在onShareAppMessage方法中 加uni.showShareMenu和 wx.updateShareMenu这两个方法 就可以实现需求 onShareAppMessage(){var that this;uni.showShareM…

小红书APP群控实战

设备清单 魅蓝Note5 4台 sim卡 4张 USB连接线TypeC 4根 优越者(UNITEK)USB分线器带独立电源 1台 PC i5 8g内存 1台 无线路由器 1台 硬件环境 实景 软件环境 魅蓝NOTE5 Xposed Installer 3.1.5 Xposed Version 89 Just Trust Me 0.2 小红书APP 6.8 使用手机号注册小红书账号…

小红书数据平台:笔记爆文率提升的三大秘诀公式!

导语 对于小红书商家 / 博主来说&#xff0c;写出爆文就像买彩票&#xff0c;根本不能预知哪一篇会爆。2023年&#xff0c;小红书哪些内容会脱颖而出呢&#xff1f;我们又该如何把握热点趋势&#xff0c;实现优质内容转化出爆文~ 美妆作为小红书的长红赛道&#xff0c;本文我…

详解小红书引流小技巧和矩阵玩法

众所周知&#xff0c;在各大公共领域平台中&#xff0c;小红书这个平台可以说是最受品牌商家关注的战场之一。而且作为一个种草平台&#xff0c;相比其他平台&#xff0c;小红书用户搜索的目的性更加精准&#xff0c;那么我们如何才能将公域流量引导到个人领域并获得准确的流量…

3.27 分享两个在PC上浏览小红书内容的方法【玩赚小红书】

第一个&#xff1a;微信小程序 可以通过登录电脑端的微信&#xff0c;在微信里面搜索小红书小程序使用&#xff0c;同时也可以添加到桌面。 ​ ​ ​ 方法二&#xff1a;通过搜索引擎跳转 给大家分享一下如何在浏览器中搜索&#xff0c;&#xff08;以bing搜索引擎为例&…