牛客社区项目续

news2024/9/20 15:01:09

统一日志记录

我们的这个项目在很多地方都需要记录日志,比如帖子模块、评论模块、消息模块等,而以前我们记录日志都是在某一个功能点中使用日志工厂,像下面这样:

 

项目中很多地方都需要记录日志,像这样一个地方一个地方的记录将会很麻烦,而我们只需要将这个记录日志的功能抽离出来,利用AOP的思想去实现即可。关于AOP可以看我的另一篇博客:Spring AOP_aop切面由哪些构成_咸鱼吐泡泡的博客-CSDN博客

 

@Component
@Aspect
public class ServiceLogAspect {
    private static final Logger logger = LoggerFactory.getLogger(ServiceLogAspect.class);

    @Pointcut("execution(* com.nowcoder.community.service.*.*(..))")
    public void pointcut(){

    }

    @Before("pointcut()")
    public void before(JoinPoint joinPoint){
        // 用户[1.2.3.4],在[xxx],访问了[com.nowcoder.community.service.xxx()].
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String ip = request.getRemoteHost();
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        String target = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        logger.info(String.format("用户[%s],在[%s],访问了[%s].",ip,now,target));
    }
}

 当我访问该项目的主页面的时候:

查看用户帖子列表、查看点赞和回帖等功能会被访问,像下面这样:

Redis

关于Redis的详细介绍请看我的这篇博客:

(1条消息) Redis的常见操作和Session的持久化_redis删除session_咸鱼吐泡泡的博客-CSDN博客

windows系统下载Redis地址:

GitHub - microsoftarchive/redis: Redis is an in-memory database that persists on disk. The data model is key-value, but many different kind of values are supported: Strings, Lists, Sets, Sorted Sets, Hashes 

下载好以后一路next即可,过程中注意将文件的位置设置到环境变量中

 然后在控制台中检验Redis是否安装成功:

然后就可以进行相关的操作了。

 Spring整合Redis

		<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>

#RedisProperties
spring.redis.database=11
spring.redis.host=localhost
spring.redis.port=6379
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String,Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        //设置key的序列化方式
        template.setKeySerializer(RedisSerializer.string());
        //设置value的序列化方式
        template.setValueSerializer(RedisSerializer.json());
        //设置hash的key的序列化方式
        template.setHashKeySerializer(RedisSerializer.string());
        //设置hash的value的序列化方式
        template.setHashKeySerializer(RedisSerializer.json());

        template.afterPropertiesSet();
        return template;
    }
}
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class RedisTest {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testString(){
        String redisKey = "test:count";
        redisTemplate.opsForValue().set(redisKey,1);
        System.out.println(redisTemplate.opsForValue().get(redisKey));
        System.out.println(redisTemplate.opsForValue().increment(redisKey));
        System.out.println(redisTemplate.opsForValue().decrement(redisKey));

    }

    @Test
    public void testHsahes(){
        String redisKey = "test:user";

        redisTemplate.opsForHash().put(redisKey,"id",1);
        redisTemplate.opsForHash().put(redisKey,"username","zhangsan");

        System.out.println(redisTemplate.opsForHash().get(redisKey,"id"));
        System.out.println(redisTemplate.opsForHash().get(redisKey,"username"));
    }

    @Test
    public void testLists(){
        String redisKey = "test:ids";
        redisTemplate.opsForList().leftPush(redisKey,101);
        redisTemplate.opsForList().leftPush(redisKey,102);
        redisTemplate.opsForList().leftPush(redisKey,103);

        System.out.println(redisTemplate.opsForList().size(redisKey));
        System.out.println(redisTemplate.opsForList().index(redisKey,0));
        System.out.println(redisTemplate.opsForList().range(redisKey,0,2));

        System.out.println(redisTemplate.opsForList().leftPop(redisKey));
        System.out.println(redisTemplate.opsForList().leftPop(redisKey));
        System.out.println(redisTemplate.opsForList().leftPop(redisKey));
    }

    @Test
    public void testSets(){
        String redisKey = "test:teachers";

        redisTemplate.opsForZSet().add(redisKey,"王名桥",80);
        redisTemplate.opsForZSet().add(redisKey,"黄启鹏",90);
        redisTemplate.opsForZSet().add(redisKey,"阿资区不",50);
        redisTemplate.opsForZSet().add(redisKey,"王磊",70);
        redisTemplate.opsForZSet().add(redisKey,"找文康",60);

        System.out.println(redisTemplate.opsForZSet().zCard(redisKey));
        System.out.println(redisTemplate.opsForZSet().score(redisKey,"王名桥"));
        System.out.println(redisTemplate.opsForZSet().reverseRank(redisKey,"王名桥"));
        System.out.println(redisTemplate.opsForZSet().reverseRange(redisKey,0,2));

    }

    //批量发送命令,节约网络开销
    @Test
    public void testBoundOperations(){
        String redisKey = "test:count";
        BoundValueOperations operations = redisTemplate.boundValueOps(redisKey);
        operations.increment();
        operations.increment();
        operations.increment();
        operations.increment();
        operations.increment();
        System.out.println(operations.get());
    }
    //编程式事物
    @Test
    public void testTransaction(){
        Object result = redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations redisOperations) throws DataAccessException {
                String redisKey = "test:tx";
                //启用事物
                redisOperations.multi();
                redisOperations.opsForSet().add(redisKey,"张三");
                redisOperations.opsForSet().add(redisKey,"list");
                redisOperations.opsForSet().add(redisKey,"wangwu");
                System.out.println(redisOperations.opsForSet().members(redisKey));

                //提交事物
                return redisOperations.exec();
            }
        });
        System.out.println(result);
    }

}

利用Redis实现点赞、查看点赞功能

代码看:牛客社区————利用Redis实现点赞功能 · 591dbf7 · 王磊/实战项目 - Gitee.com 

牛客社区————利用Redis实现查看收到的点赞功能 · a1bc221 · 王磊/实战项目 - Gitee.com

利用Redis实现关注、取消关注功能 

代码看:牛客社区————利用Redis实现关注、取消关注功能 · 49c1c58 · 王磊/实战项目 - Gitee.com 

利用Redis实现查看关注列表和粉丝列表的功能 

代码看:牛客社区————利用Redis实现查看关注列表和粉丝列表的功能 · 2fab6d9 · 王磊/实战项目 - Gitee.com

优化登录模块

代码看:牛客社区————利用Redis优化登录模块 · d4d4d76 · 王磊/实战项目 - Gitee.com 

阻塞队列 

public class BlockingQueueTests {

    public static void main(String[] args) {
        BlockingQueue queue = new ArrayBlockingQueue(10);
        new Thread(new Producer(queue)).start();
        new Thread(new Consumer(queue)).start();
        new Thread(new Consumer(queue)).start();
        new Thread(new Consumer(queue)).start();
    }

}

class Producer implements Runnable {

    private BlockingQueue<Integer> queue;

    public Producer(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            for (int i = 0; i < 100; i++) {
                Thread.sleep(20);
                queue.put(i);
                System.out.println(Thread.currentThread().getName() + "生产:" + queue.size());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

class Consumer implements Runnable {

    private BlockingQueue<Integer> queue;

    public Consumer(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            while (true) {
                Thread.sleep(new Random().nextInt(1000));
                queue.take();
                System.out.println(Thread.currentThread().getName() + "消费:" + queue.size());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

kafka 

windows中下载使用kafka 

下载链接:Apache Kafka 

下载完以后一路next即可,然后就是修改kafka里面的配置文件:

使用kafka  

在控制台中启动zookeeper和kafka:

 Spring整合kafka

		<dependency>
			<groupId>org.springframework.kafka</groupId>
			<artifactId>spring-kafka</artifactId>
		</dependency>
#KafkaProperties
spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.consumer.group-id=test-consumer-group
spring.kafka.consumer.enable-auto-commit=true
spring.kafka.consumer.auto-commit-interval=3000

上面的group-id在consumer.properties配置文件中有:

可以改,也可以不改,但是改了以后要重启kafka服务才能生效

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class KafkaTests {
    @Autowired
    private KafkaProducer kafkaProducer;
    
    @Test
    public void testKafka(){
        kafkaProducer.sendMessage("test","你好");
        kafkaProducer.sendMessage("test","在吗");
        try {
            Thread.sleep(1000 * 10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

@Component
class KafkaProducer{
    @Autowired
    private KafkaTemplate kafkaTemplate;
    public void sendMessage(String topic,String content){
        kafkaTemplate.send(topic,content);
    }
}

@Component
class KafkaConsumer{
    @KafkaListener(topics = {"test"})
    public void handleMessage(ConsumerRecord record){
        System.out.println(record.value());
    }
}

 

利用kafka来发送系统通知

代码:牛客社区————利用kafka来发送系统消息 · afdb10e · 王磊/实战项目 - Gitee.com

利用kafka来接收并显示系统消息 

 代码:牛客社区————利用kafka来查看系统通知和通知详情 · 7e4ec1c · 王磊/实战项目 - Gitee.com

Elasticserch分布式搜索引擎

Elasticserch和Elasticsearch-analysis-ik的下载 

Download Elasticsearch | Elastic

GitHub - medcl/elasticsearch-analysis-ik: The IK Analysis plugin integrates Lucene IK analyzer into elasticsearch, support customized dictionary.

注意一定要将Elaticsearch-analysis-ik的安装包解压到elasticsearch目录下面的ik目录中(ik目录自己创建)

配置elasticsearch 

然后配置elasticsearch的环境变量 

在windows命令行中使用elasticsearch 

使用postman来操作elaticsearch 

 Spring整合Elasticsearch

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
		</dependency>

#配置集群名字和集群中的节点
#ElasticsearchProperties
spring.data.elasticsearch.cluster-name=nowcoder
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300

代码:牛客社区————Spring整合Elasticsearch · 3fca7db · 王磊/实战项目 - Gitee.com 

 利用Elasticsearch实现社区搜索功能

 代码:牛客社区————利用Elasticsearch实现社区搜索功能 · 84eaa18 · 王磊/实战项目 - Gitee.com

利用SpringSecurity来做权限管理 

有关SpringSecurity可以去看我的另一篇博客 

代码:

牛客社区————利用SpringSecurity来做权限管理

利用SpringSecurity对帖子进行加精、置顶、删除操作

代码:

牛客社区————利用SpringSecurity对帖子进行置顶、加精、删除操作

Redis高级数据类型

 代码:

牛客社区————Redis高级数据类型

利用SpringSecurity和Reids高级数据类型来做统计网站数据 

代码:

牛客社区————利用SpringSecurity和Reids高级数据类型来做统计网站数据

学习使用QUARTZ 

定时任务的主要作用:每隔一段时间去执行一个任务。

使用quartz来解决问题,首先要Job接口来定义一个任务 ,然后通过JobDetail和Trigger接口来配置这个Job。配置好以后,启动程序,程序就会去读取配置信息,将读取到的配置信息存储到数据库里面。当后面再次启动时,程序就会去读取数据库表里面存储的信息,也就是说配置只执行一次,只在程序第一次执行的时候配置。

代码:

牛客社区————学习使用QUARTZ

利用QUARTZ来做热帖排行 

代码:

牛客社区————利用QUARTZ来做热帖排行

利用wkhtmltoimage工具生成长图 

打开wkhtmltopdf 网站下载wkhtmltoimage工具:

配置环境变量:

创建将网页生成pdf或者图片的文件夹:

测试:

 

生成的图片的时候,压缩图片的大小:

  

--quality 75wkhtmltoimage 工具的一个选项,用于设置图像生成的质量 

代码:

牛客社区————利用wkhtmltoimage工具生成长图

利用七牛云来完成用户头像的文件的上传

七牛云相关操作 

点击链接https://portal.qiniu.com

注册一个账户,完成各项实名认证和绑定,然后点击主页里面的控制台,来到对象存储区域:

记住上面的测试域名,配置到你自己的项目里面,如果你有备案的自定义域名,可以使用你自己的。 

在项目里面配置七牛云 

引入七牛云依赖

		<dependency>
			<groupId>com.qiniu</groupId>
			<artifactId>qiniu-java-sdk</artifactId>
			<version>7.2.23</version>
		</dependency>

配置七牛云 

qiniu.key.access=41nFpZ4QO6fz42iVBcDjUNivnsT3ZyGYeLyOaCF5
qiniu.key.secret=-DN1XDSx5oxLh6fztFBicBp44z5cqAuNGo893JSD
qiniu.bucket.header.name=nowcoder-heade
quniu.bucket.header.url=rwjnl2lgl.hn-bkt.clouddn.com
qiniu.bucket.share.name=nowcoder-file
qiniu.bucket.share.url=rwjok8qz5.hn-bkt.clouddn.com

上面是用于设置七牛云存储(Qiniu Cloud Storage)的相关参数。以下是对每个配置项的解释:

1. `qiniu.key.access`:七牛云存储的访问密钥 Access Key,用于身份验证和访问权限控制。这个值应该是你在七牛云存储平台获取到的访问密钥的 Access Key。

2. `qiniu.key.secret`:七牛云存储的访问密钥 Secret Key,用于与访问密钥 Access Key 相配合进行身份验证和访问权限控制。这个值应该是你在七牛云存储平台获取到的访问密钥的 Secret Key。

3. `qiniu.bucket.header.name`:七牛云存储中用于存储头像图片的存储空间名称。这个配置项指定了用于存储头像图片的存储空间的名称。

4. `qiniu.bucket.header.url`:七牛云存储中用于存储头像图片的存储空间的访问域名。这个配置项指定了用于访问头像图片的存储空间的域名。

5. `qiniu.bucket.share.name`:七牛云存储中用于存储共享文件的存储空间名称。这个配置项指定了用于存储共享文件的存储空间的名称。

6. `qiniu.bucket.share.url`:七牛云存储中用于存储共享文件的存储空间的访问域名。这个配置项指定了用于访问共享文件的存储空间的域名。

然后写相关的上传文件的业务

在我们的业务中,异步请求里面的js文件中需要用到七牛云存储区域的域名,这个域名的查找过程如下:

 代码

牛客社区————将文件上传到七牛云云服务器

使用caffeine来做本地缓存 

二级缓存 

三级缓存 

代码:

牛客社区————使用caffeine来做本地缓存

项目的压力测试 

JMeter 

下载并解压打开:

启动项目 

配置JMeter (做测试计划)

可以看到在没做本地缓存之前服务器每秒钟最多处理5个请求,看一下做了本地缓存后的效果:

可以发现做了本地缓存以后服务器二点性能提升了几十倍。 

项目发布前的单元测试 

在我们单元测试种,有可能会涉及到一个测试方法加载数据,另一个测试方法删除数据,这种情况是会存在的,比如查询数据库表中的测试,另一个测试是删除数据库种的表 ,这样的测试有个特点就是只能执行一次。但是当后面如果需求改变了,比如查询数据库以后要对数据库中的数据做操作时,这是因为数据库中已经没有数据了,因此就会报错。为了避免上面的这些情况,就需要单独初始化一份数据,供这些测试方法使用。

而我们不可能每次测试就去手动初始化数据,好在SpringBoot为我们提供了下面这些注解:

下面演示这些注解的使用:

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class SpringBootTests {
    @BeforeClass
    public static void beforeClass() {
        System.out.println("beforeClass");
    }

    @AfterClass
    public static void afterClass() {
        System.out.println("afterClass");
    }

    @Before
    public void before() {
        System.out.println("before");
    }

    @After
    public void after() {
        System.out.println("after");
    }

    @Test
    public void test1() {
        System.out.println("test1");
    }

    @Test
    public void test2() {
        System.out.println("test2");
    }
    

}

当运行test1和test2时:

在Spring Boot中,`@BeforeClass`、`@AfterClass`、`@Before`、`@After`这些注解并不是Spring Boot特有的,而是来自JUnit测试框架(JUnit 4)的注解。这些注解用于在测试方法的执行过程中定义一些预处理和后处理的操作。

1. `@BeforeClass`:该注解表示在测试类中的所有测试方法执行之前运行的方法。通常用于设置测试环境的准备工作,例如加载配置文件、初始化数据库连接等。被`@BeforeClass`注解修饰的方法必须是静态方法,并且只会执行一次。

2. `@AfterClass`:该注解表示在测试类中的所有测试方法执行之后运行的方法。通常用于进行一些资源的清理操作,例如关闭数据库连接、释放资源等。被`@AfterClass`注解修饰的方法必须是静态方法,并且只会执行一次。

3. `@Before`:该注解表示在每个测试方法执行之前运行的方法。通常用于执行一些初始化操作,例如创建对象、准备测试数据等。被`@Before`注解修饰的方法会在每个测试方法执行之前都被调用。

4. `@After`:该注解表示在每个测试方法执行之后运行的方法。通常用于执行一些清理操作,例如删除临时文件、恢复测试环境等。被`@After`注解修饰的方法会在每个测试方法执行之后都被调用。

这些注解的使用可以帮助测试代码的编写和维护,提供了更好的测试控制和测试环境的管理。在Spring Boot中,通常会将这些注解与JUnit的`@Test`注解一起使用,以实现对测试方法的预处理和后处理操作。

请注意,从JUnit 5开始,上述的`@BeforeClass`和`@AfterClass`注解已被废弃,而是使用`@BeforeAll`和`@AfterAll`注解来代替。而`@Before`和`@After`注解仍然保持不变。因此,在使用JUnit 5及更高版本时,请使用新的注解来替代旧的注解。

根据上面 的信息,就可以在带有@BeforeClass的方法中初始化数据。

测试:

package com.nowcoder.community;

import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.service.DiscussPostService;
import org.junit.*;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Date;

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class SpringBootTests {

    @Autowired
    private DiscussPostService discussPostService;

    private DiscussPost data;

    @BeforeClass
    public void beforeClass() {
        System.out.println("beforeClass");
    }

    @AfterClass
    public static void afterClass() {
        System.out.println("afterClass");
    }

    @Before
    public void before() {
        System.out.println("before");

        // 初始化测试数据
        data = new DiscussPost();
        data.setUserId(111);
        data.setTitle("Test Title");
        data.setContent("Test Content");
        data.setCreateTime(new Date());
        discussPostService.addDiscussPost(data);
    }

    @After
    public void after() {
        System.out.println("after");

        // 删除测试数据
        discussPostService.updateStatus(data.getId(), 2);
    }

    @Test
    public void test1() {
        System.out.println("test1");
    }

    @Test
    public void test2() {
        System.out.println("test2");
    }

    @Test
    public void testFindById() {
        DiscussPost post = discussPostService.selectDiscussPost(data.getId());
        Assert.assertNotNull(post);
        Assert.assertEquals(data.getTitle(), post.getTitle());
        Assert.assertEquals(data.getContent(), post.getContent());
    }

    @Test
    public void testUpdateScore() {
        int rows = discussPostService.updateScore(data.getId(), 2000.00);
        Assert.assertEquals(1, rows);

        DiscussPost post = discussPostService.selectDiscussPost(data.getId());
        Assert.assertEquals(2000.00, post.getScore(), 2);
    }


}

上面每次执行testFindById和testUpdateScore方法时都会先执行before方法,当这两个方法执行完以后又会执行after方法。 

利用SpringBoot Actuator来做项目的监控 

添加依赖:

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>

访问服务器:

上面是访问SpringBoot Actuator默认暴露的两个端点,如果想要暴露其他端点,需要做配置:

management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=info,caches

对上面的配置的解释:

在Spring Boot中,`management.endpoints.web.exposure.include`和`management.endpoints.web.exposure.exclude`是用于配置管理端点(actuator endpoints)在Web暴露中的包含和排除规则。

Actuator是Spring Boot提供的一个功能强大的模块,用于监控和管理应用程序。它提供了多个端点(endpoints),例如/health、/info、/metrics等,可以通过HTTP访问这些端点来获取应用程序的各种信息、指标和执行一些管理操作。

下面是对这两个配置属性的解释:

1. `management.endpoints.web.exposure.include`:该属性用于配置需要包含在Web暴露中的管理端点。使用逗号分隔多个端点名称或使用通配符来表示所有端点。例如,`management.endpoints.web.exposure.include=*`表示将所有管理端点都包含在Web暴露中。

2. `management.endpoints.web.exposure.exclude`:该属性用于配置需要排除在Web暴露中的管理端点。使用逗号分隔多个端点名称。例如,`management.endpoints.web.exposure.exclude=info,caches`表示将/info和/caches两个端点排除在Web暴露之外。

这些属性的配置可以在`application.properties`或`application.yml`文件中进行设置,用于灵活控制管理端点在Web访问中的可见性。通过合理配置这些属性,可以确保管理端点只对需要的角色或权限开放,提高应用程序的安全性。

请注意,管理端点的访问路径默认为`/actuator`,可以通过其他配置属性进行自定义,例如`management.endpoints.web.base-path`。

自定义端点 (监控个性化的东西)

//对数据库连接做监控
@Component
@Endpoint(id = "database")
public class DatabaseEndpoint {

    private static final Logger logger = LoggerFactory.getLogger(DatabaseEndpoint.class);

    @Autowired
    private DataSource dataSource;

    @ReadOperation
    public String checkConnection() {
        try (
                Connection conn = dataSource.getConnection();
        ) {
            return CommunityUtil.getJSONString(0, "获取连接成功!");
        } catch (SQLException e) {
            logger.error("获取连接失败:" + e.getMessage());
            return CommunityUtil.getJSONString(1, "获取连接失败!");
        }
    }

}

自定义端点以后记得做权限配置,不然任何人都能访问。 

代码:

牛客社区————利用SpringBoot Actuator来做项目的监控

项目的部署 

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

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

相关文章

sumo的几种安装方法

sumo的几种安装方法 sumo有很多中安装方法&#xff0c;根据你需要的任务来自己选择&#xff1a; 采用官网的latest version来进行安装 sudo add-apt-repository ppa:sumo/stable sudo apt-get update sudo apt-get install sumo sumo-tools sumo-doc想要安装源码来进行自己b…

【Java可执行命令】(六)调试工具 jdb:深入解析应用程序调试工具jdb ~

Java可执行命令详解之jdb 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 语法格式3.1.1 参数&#xff1a;-sourcepath < path>3.1.2 指令&#xff1a;run [class [args]]3.1.3 指令&#xff1a;print < expr>3.1.4 指令&#xff1a;stop at< class>:< line>…

如何利用Idea回滚代码以及Cherry-Pick部分代码

引言 大家在版本迭代过程中&#xff0c;是否遇到过开发好的需求&#xff0c;都已经合并到Master分支等待发布后&#xff0c;临时通知不需要上线了的情况。这个时候一般会要求只上一部分紧急功能或者别的新功能&#xff0c;那么这个时候就需要用到Git的Reset以及Cherry-Pick功能…

钉钉机器人用bitmap实现签到记录

现在是周五晚上&#xff0c;下面是一个二进制数字&#xff0c;其中&#xff0c;有16位&#xff0c;最后一位下标是15&#xff0c;今天晚上是14&#xff0c;我签到成功了

一定要收藏的30套可视化大屏制作模板!升职加薪不再是梦想!

前几天和朋友吃饭聊天&#xff0c;他吐槽说老板让他做可视化大屏&#xff0c;但他不会敲代码根本做不出来&#xff0c;老板动动嘴巴子根本不考虑技术难度只想看到成果&#xff0c;他焦虑得都睡不着觉。我给他分享了一套可视化大屏模板&#xff0c;10分钟就制作完成了老板要求的…

了解浏览器缓存

什么是HTTP缓存&#xff0c;如何工作的&#xff1f; 当我们打开一个页面时&#xff0c;会向服务端发起很多次请求&#xff0c;如下图打开百毒首页&#xff0c;发起了HTML、各种图片、JS、CSS等资源共101次请求。这里面很多资源并不会频繁变化&#xff0c;每次打开页面都重新请…

利用Python构建宁德时代、比亚迪、隆基绿能股票时间序列预测模型

存货 import tushare as ts # 导包 import numpy as np import matplotlib.pyplot as plt from scipy.signal import find_peaks from scipy.stats import norm import datetime import pandas as pd import seaborn as sns # pip install seaborn import matplotlib.patches …

Oracle报错:“Error in invoking target ‘agent nmhs’ of makefile...”

前言&#xff1a;Oracle在安装过程中的报错一定要重视&#xff0c;这决定你后续是否能完成安装以及是否能使用。我这边会陆续汇总一些报错现象以及解决方案共享。 ##Install Product 86%报错信息 &#xff1a;“Error in invoking target agent nmhs of makefile...”解决方案…

意大利语翻译哪个公司比较专业?

据了解&#xff0c;意大利语除了通行于意大利之外&#xff0c;还通行于美国、加拿大、阿根廷和巴西等29个国家的&#xff0c;其应用极为广泛。随着意大利语翻译需求量的日益增加&#xff0c;也促进了意大利语与其它语言间的交流、转化和发展。那么&#xff0c;意大利语翻译难吗…

抖音短视频矩阵号系统开源部署搭建分享(二)

开发背景&#xff1a;抖音seo源码&#xff0c;抖音矩阵系统源码。抖音获客系统源码&#xff0c;短视频矩阵系统源码开源搭建&#xff08;MySQL数据库&#xff0c;NGINX&#xff0c;PHP7.4&#xff0c;MySQL5.7&#xff0c;redis&#xff09; 技术要点&#xff1a; 服务器配置服…

vue-router.esm.js:2248 Error: Cannot find module ‘@/views/dylife/ 报错解决

具体是展示 一直加载 控制台报找不到模块 webpack版本问题&#xff0c;webpack4 不支持变量方式的动态 import &#xff0c;新版本需要使用 require() 来解决此问题。 return () > import(/views/${view}) 改写成 return (resolve) > require([/views/${view}], reso…

python接口自动化(四)--接口测试工具介绍(详解)

简介 “工欲善其事必先利其器”&#xff0c;通过前边几篇文章的介绍&#xff0c;大家大致对接口有了进一步的认识。那么接下来让我们看看接口测试的工具有哪些。 目前&#xff0c;市场上有很多支持接口测试的工具。利用工具进行接口测试&#xff0c;能够提供测试效率。例如&…

【C++】浅析C++中的虚函数

关于虚函数 Q1&#xff1a;观察一个类引入虚函数后&#xff0c;类会发生什么变化&#xff1f; 首先&#xff0c;创建一个空类A&#xff0c;并实例化出A的一个对象a&#xff0c;计算一下这个对象占用多少字节&#xff1a; #include<iostream> using namespace std;clas…

02-阴影

使用阴影 1.给立方体添加castShadow&#xff0c;让立方体产生阴影 cube.castShadow true;2.创建一个地面用于接收阴影 const planeGemetry new THREE.PlaneGeometry(20, 30)const planeMaterial new THREE.MeshPhongMaterial({ color: 0xffffff })const plane new THREE.…

LeetCode 2. 两数相加

文章目录 1. 题目描述2. 解题代码 1. 题目描述 链接&#xff1a;https://leetcode.cn/problems/add-two-numbers/ 2. 解题代码 public ListNode AddTwoNumber(ListNode l1, ListNode l2) {ListNode head new ListNode();ListNode cur head;int carry 0;while (l1 ! null…

CIO 访谈|财达证券 IT 基础架构云化转型思考与实践

作为河北省证券行业的主力军&#xff0c;财达证券始终坚持用科技赋能业务&#xff0c;全方位推动信息化和数字化建设。在本期视频中&#xff0c;我们请到了财达证券首席信息官谢井民&#xff0c;分享如何基于 SmartX 超融合逐步实现 IT 基础架构云化转型&#xff0c;满足公司“…

RPC框架(一):扫盲

文章目录 一、概要二、RPC组成部分三、影响RPC框架性能的因素 一、概要 RPC作用&#xff1f; 让不同服务间调用方法像同一服务间调用本地方法一样 二、RPC组成部分 Client&#xff1a;RPC协议调用方 Server&#xff1a;远程服务方法的具体实现 Stub/Proxy&#xff1a;RPC代…

基于SpringBoot的家庭理财记账系统的设计与开发

1.引言 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个…

Apache组件POI,将图片下载到Excel文件中并导出。

在日常的工作中&#xff0c;有时我们会遇到需要将数据库表中图片字段下载到Excel中的需求&#xff0c;为方便各位小伙伴今后的开发工作&#xff0c;我将分享出自己写的代码&#xff0c;在文章末尾有我上传到 Gitee 上的 Demo案例&#xff0c;希望大家喜欢。 将图片下载到Excel文…

[CKA]考试之Deployment管理pod扩缩容

由于最新的CKA考试改版&#xff0c;不允许存储书签&#xff0c;本博客致力怎么一步步从官网把答案找到&#xff0c;如何修改把题做对&#xff0c;下面开始我们的 CKA之旅 题目为&#xff1a; Task 扩容 deployment guestbook 为 6个pod 注意&#xff0c;如果题目要求先切换K8…