牛客论坛笔记~

文章目录

  • Redis
    • spring整合redis
    • 实现点赞
      • 帖子的赞
      • 用户的赞
  • 关注功能
    • 热帖排行
    • redis存储验证码、登录凭证、用户信息
  • kafka
    • 阻塞队列
    • kafka![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d35be55986344b548710985cd8ecbd87.png)
    • 触发事件
    • 处理事件
  • Redis高级
    • 网站数据统计
  • 实现搜索功能
    • 实现的功能
    • 1. elasticsearch基本设置
    • 2. 实现数据同步
    • 3. es搜索并分页、高亮的功能
    • 4. 实现搜索功能
  • Quarzt
    • 任务调度

Redis

在这里插入图片描述

redis-cli
select 0
# 加值减值
incr count decr count
# 查询库中所有的key
keys *
# 以test开头的所有的key
keys test*
# key的类型, 名为test:user的key
type test:user
# key是否存在
exists test:user
del test:user# 删除
#过期时间, 10秒过期
expire test:user 10

在这里插入图片描述

spring整合redis

在这里插入图片描述

实现点赞

帖子的赞

like:entity:entityType:entityId 实体的赞中存的是用户id, 可以更好的适应各种需求–>set(userId)–无序唯一

  • 点一次是点赞,再点一次是取消赞
  • 先看集合中有没有userId,operations.opsForSet().isMember(entityLikeKey, userId) 如果存在,就删除。不存在就添加
public void like(int userId,int entityType,int entityId,int entityUserId){
    //  事务
       redisTemplate.execute(new SessionCallback() {
           @Override
           public Object execute(RedisOperations operations) throws DataAccessException {
               String entityLikeKey= RedisKeyUtil.getEntityLikeKey(entityType,entityId);
               // 用户该帖子获得的赞
               String userLikeKey=RedisKeyUtil.getUserLikeKey(entityUserId);
               Boolean isMember = operations.opsForSet().isMember(entityLikeKey, userId);
               operations.multi();//开启事务
               if(isMember){
                   operations.opsForSet().remove(entityLikeKey,userId);
                   operations.opsForValue().decrement(userLikeKey);
               }else {
                   operations.opsForSet().add(entityLikeKey,userId);
                   operations.opsForValue().increment(userLikeKey);
               }
               return operations.exec();//执行事务
           }
       });
   }
  • 查询某实体(帖子)的点赞数量
  • 查询用户是否给实体点赞
  • 查询某个用户获得的赞
// 查询某实体点赞的数量
    public long findEntityLikeCount(int entityType,int entityId){
        String entityLikeKey=RedisKeyUtil.getEntityLikeKey(entityType,entityId);
        return redisTemplate.opsForSet().size(entityLikeKey);
    }
    //查询某人对某实体的点赞状态
    public int findEntityLikeStatus(int userId,int entityType,int entityId){
        String entityLikeKey=RedisKeyUtil.getEntityLikeKey(entityType,entityId);
        return redisTemplate.opsForSet().isMember(entityLikeKey,userId)?1:0;
 //查询某个用户的赞的数量
    public int findUserLikeCount(int userId){
        String userLikeKey = RedisKeyUtil.getUserLikeKey(userId);
        Integer count = (Integer) redisTemplate.opsForValue().get(userLikeKey);

        return count==null?0:count.intValue();
    }
    }

用户的赞

like:user:userId

关注功能

  • 某个用户关注的所有实体
    followee:userId:entityType ->Zset(entityId,now) 按时间排序
  • 实体的粉丝
    follower:entityType:entityId ->Zset(userId,now)

关注取关的功能实现

 public void follow(int userId,int entityType,int entityId){
        redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                String followeeKey= RedisKeyUtil.getFolloweeKey(userId,entityType);
                String followerKey= RedisKeyUtil.getFollowerKey(entityId,entityType);
                operations.multi();
                operations.opsForZSet().add(followeeKey,entityId,System.currentTimeMillis());
                operations.opsForZSet().add(followerKey,userId,System.currentTimeMillis());
                return operations.exec();
            }
        });
    }
    public void unfollow(int userId,int entityType,int entityId){
        redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                String followeeKey= RedisKeyUtil.getFolloweeKey(userId,entityType);
                String followerKey= RedisKeyUtil.getFollowerKey(entityId,entityType);
                operations.multi();
                operations.opsForZSet().remove(followeeKey,entityId);
                operations.opsForZSet().remove(followerKey,userId);
                return operations.exec();
            }
        });
    }
  • 查询关注实体的数量
  • 查询实体粉丝的数量
  • 查询当前用户是否已关注这个实体
    粉丝列表、关注列表
  • 查询某用户关注的人
  • 查询某用户的粉丝
//查询某用户关注的人
    public List<Map<String,Object>> findFollowees(int userId,int offset,int limit){
        String followeeKey= RedisKeyUtil.getFolloweeKey(userId,ENTITY_TYPE_USER);
        Set<Integer> targetIds=redisTemplate.opsForZSet().reverseRange(followeeKey,offset,offset+limit-1);
        if(targetIds==null){
            return null;
        }
        List<Map<String,Object>> list=new ArrayList<>();
        for(Integer targetId:targetIds){
            Map<String,Object> map=new HashMap<>();
            User user = userService.findUserById(targetId);
            map.put("user",user);
            Double score=redisTemplate.opsForZSet().score(followeeKey,targetId);
            map.put("followTime",new Date(score.longValue()));
            list.add(map);
        }
        return list;
    }

    //查询某用户的粉丝
    public List<Map<String,Object>> findFollowers(int userId,int offset,int limit){
        String followerKey= RedisKeyUtil.getFollowerKey(userId,ENTITY_TYPE_USER);
        Set<Integer> targetIds=redisTemplate.opsForZSet().reverseRange(followerKey,offset,offset+limit-1);
        if(targetIds==null){
            return null;
        }
        List<Map<String,Object>> list=new ArrayList<>();
        for(Integer targetId:targetIds){
            Map<String,Object> map=new HashMap<>();
            User user = userService.findUserById(targetId);
            map.put("user",user);
            Double score=redisTemplate.opsForZSet().score(followerKey,targetId);
            map.put("followTime",new Date(score.longValue()));
            list.add(map);
        }
        return list;
    }

热帖排行

在这里插入图片描述

// 帖子分数
    public static String getPostScoreKey() {
        return PREFIX_POST + SPLIT + "score";
    }
  • 评论、加精、点赞、收藏时,对帖子算分数
  • 将需要重新计算分数的帖子Id存入Redis中
// 保存需要计算帖子分数的id
            String redisKey = RedisKeyUtil.getPostScoreKey();
            redisTemplate.opsForSet().add(redisKey, discussPostId);
  • 定时刷新分数,五分钟一次
  • quartz对帖子分数进行计算
    private void refresh(int postId) {
        DiscussPost post = discussPostService.findDiscussPostById(postId);
        if(post == null) {
            logger.error("该帖子不存在:id=" + postId);
            return;
        }
        // 是否精华
        boolean wonderful = post.getStatus() == 1;
        // 评论数量
        int commentCount = post.getCommentCount();
        // 点赞数量
        long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, postId);

        // 计算权重
        double w = (wonderful ? 75 : 0) + commentCount * 10 + likeCount * 2;
        // 分数 = 帖子权重 + 距离天数
        double score = Math.log10(Math.max(w, 1)) + (post.getCreateTime().getTime()-epoch.getTime()) / (1000 * 3600 * 24);
        // 更新帖子分数
        discussPostService.updateScore(postId, score);
        // 同步搜索的数据
        post.setScore(score);
        elasticSearchService.saveDiscussPost(post);
    }

配置quartz

    // 刷新帖子分数任务
    @Bean
    public JobDetailFactoryBean postScoreRefreshJobDetail(){
        JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
        factoryBean.setJobClass(PostScoreRefreshJob.class);
        factoryBean.setName("postScoreRefreshJob");
        factoryBean.setGroup("communityJobJobGroup");
        factoryBean.setDurability(true); // 持久化
        factoryBean.setRequestsRecovery(true);
        return factoryBean;

    }
    @Bean
    public SimpleTriggerFactoryBean postScoreRefreshTrigger(JobDetail postScoreRefreshJobDetail){
        SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
        factoryBean.setJobDetail(postScoreRefreshJobDetail);
        factoryBean.setName("postScoreRefreshTrigger");
        factoryBean.setGroup("communityTriggerGroup");
        factoryBean.setRepeatInterval(1000 * 60 * 5); // 频率
        factoryBean.setJobDataMap(new JobDataMap()); // 存储job的状态
        return factoryBean;
    }

redis存储验证码、登录凭证、用户信息

在这里插入图片描述

  • 存储验证码时,可以给用户生成一个临时的随机字符串,用于标识用户。
  • 登录凭证,退出后,将状态改变,再存入
  • 缓存用户信息
    • 优先从缓存中取值
    • 取不到数据时,初始化缓存数据
    • 数据变更时,清除缓存数据
    //1.优先从缓存中读取数据
    public User getCache(int userId){
        String redisKey = RedisKeyUtil.getUserKey(userId);
        return (User) redisTemplate.opsForValue().get(redisKey);

    }

    //2.在缓存中读不到数据时,初始化缓存数据
    public User initCache(int userId){
        User user = userMapper.selectById(userId);
        String redisKey = RedisKeyUtil.getUserKey(userId);
        redisTemplate.opsForValue().set(redisKey,user,3600, TimeUnit.SECONDS);
        return user;

    }
    //3.数据变更时清除缓存

    private void clearCache(int userId){
        String redisKey = RedisKeyUtil.getUserKey(userId);
        redisTemplate.delete(redisKey);
    }

kafka

阻塞队列

在这里插入图片描述

kafka在这里插入图片描述

数据存到硬盘上,主副本,从副本

触发事件

将消息放入队列中
封装成事件,

  • 评论后,发布通知
    触发发帖事件
Event event=new Event()
                .setTopic(TOPIC_COMMENT)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(comment.getEntityType())
                .setEntityId(comment.getEntityId())
                .setData("postId", discussPostId);
        if(comment.getEntityType()==ENTITY_TYPE_POST){
            DiscussPost target = discussPostService.findDiscussPostById(comment.getEntityId());
            event.setEntityUserId(target.getUserId());
        }else if(comment.getEntityType()==ENTITY_TYPE_COMMENT){
            Comment target=commentService.findCommentsById(comment.getEntityId());
            event.setEntityUserId(target.getUserId());
        }

        eventProducer.fireEvent(event);
  • 点赞后, 发布通知
  • 关注后,发布通知
public class EventProducer {
    @Autowired
    private KafkaTemplate kafkaTemplate;
    //处理事件
    public void fireEvent(Event event){
        //将事件发布到指定的主题
        kafkaTemplate.send(event.getTopic(), JSONObject.toJSONString(event));
    }
}

在这里插入图片描述

处理事件

消费事件

//发送站内消息
        Message message = new Message();
        message.setFromId(SYSTEM_USER_ID);
        message.setToId(event.getEntityUserId());
        message.setConversationId(event.getTopic());
        message.setCreateTime(new Date());

        Map<String,Object> content=new HashMap<>();
        content.put("userId",event.getUserId());
        content.put("entityType",event.getEntityType());
        content.put("entityId",event.getEntityId());

        if(!event.getData().isEmpty()){
            for (Map.Entry<String ,Object> entry:event.getData().entrySet()) {
                content.put(entry.getKey(),entry.getValue());
            }
        }
        message.setContent(JSONObject.toJSONString(content));
        messageService.addMessage(message);
  • 封装事件对象
  • 开发事件的生产者
  • 开发事件的消费者

Redis高级

在这里插入图片描述

网站数据统计

在这里插入图片描述

  1. 设定redis键值
    用时间来当做rediskey
// 单日uv
    public static String getUVKey(String date){
        return PREFIX_UV + SPLIT + date;
    }
    // 区间uv
    public static String getUVKey(String startDate, String endDate){
        return PREFIX_UV + SPLIT + startDate + SPLIT + endDate;
    }
    // 单日活跃用户
    public static String getDAUKey(String date){
        return PREFIX_DAU + SPLIT + date;
    }
    // 区间活跃用户
    public static String getDAUKey(String startDate, String endDate){
        return PREFIX_DAU + SPLIT + startDate + SPLIT + endDate;
    }
  1. service层
// 将指定的IP计入UV
    public void recordUV(String ip){
        // 访问的日期作为rediskey
        String redisKey = RedisKeyUtil.getUVKey(df.format(new Date()));
        // ip地址作为值存入redis
        redisTemplate.opsForHyperLogLog().add(redisKey, ip);
    }
    // 指定统计日期范围内的UV
    public long calculateUV(Date start, Date end){
        if(start == null || end == null){
            throw new IllegalArgumentException("参数不能为空!");
        }
        // 整理该日期范围内的key
        List<String> keyList = new ArrayList<>();
        // 实例化,获取当前时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(start);
        while(!calendar.getTime().after(end)){
            String key = RedisKeyUtil.getUVKey(df.format(calendar.getTime()));
            keyList.add(key);
            // 日期往后增加一天
            calendar.add(Calendar.DATE, 1);
        }
        // 合并数据
        String redisKey = RedisKeyUtil.getUVKey(df.format(start), df.format(end));
        redisTemplate.opsForHyperLogLog().union(redisKey, keyList.toArray());
        // 返回统计的结果
        return redisTemplate.opsForHyperLogLog().size(redisKey);
    }
    // 将指定用户计入DAU
    public void recordDAU(int userId){
        String redisKey = RedisKeyUtil.getDAUKey(df.format(new Date()));
        redisTemplate.opsForValue().setBit(redisKey, userId, true);
    }
    // 统计指定日期范围内的DAU
    public long calculateDAU(Date start, Date end){
        if(start == null || end == null){
            throw new IllegalArgumentException("参数不能为空!");
        }
        // 整理该日期范围内的key
        List<byte[]> keyList = new ArrayList<>();
        // 实例化
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(start);
        while(!calendar.getTime().after(end)){
            String key = RedisKeyUtil.getDAUKey(df.format(calendar.getTime()));
            keyList.add(key.getBytes());
            calendar.add(Calendar.DATE, 1);
        }
        // 进行OR运算
        return (long) redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                String redisKey = RedisKeyUtil
                        .getDAUKey(df.format(start),df.format(end));
                connection.bitOp(RedisStringCommands.BitOperation.OR, redisKey.getBytes(),keyList.toArray(new byte[0][0]));
                return connection.bitCount(redisKey.getBytes());
            }
        });
    }

  1. 在prehandle中实现调用
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 统计UV
        String ip = request.getRemoteHost();
        dataService.recordUV(ip);
        // 统计DAU
        User user = hostHolder.getUser();
        if(user != null){
            dataService.recordDAU(user.getId());
        }
        return true;
    }

  1. controller层

实现搜索功能

实现的功能

  • 搜索服务:将帖子保存到elasticsearch服务器;从es服务器搜索、删除帖子;
  • 发布服务:发布帖子时,将帖子异步提交到es服务器;增加评论时,将帖子异步提交到es服务器;·在消费组件中增加一个方法,消费帖子发布事件;
  • 显示结果:在控制器中处理搜索请求,在HTML上显示搜索结果。

1. elasticsearch基本设置

底层是基于netty的

// 管理bean的生命周期的,初始化的方法
// 被它修饰的方法在构造器调用完以后执行
    @PostConstruct
    public void init(){
        //解决netty启动冲突问题
        System.setProperty("es.set.netty.runtime.available.processors","false");
    }

要考虑mysql中的表和es中的索引的对应关系.数据库中的字段和es的字段的对应关系

// 索引的名字,类型,分片,副本
@Document(indexName = "discusspost",type = "doc",shards=6,replicas=3)
public class DiscussPost {
	@Id
    private int id;// 主键
    @Field(type = FieldType.Integer)
    private int userId;
    // 存储的分词器和搜索的分词器
    @Field(type = FieldType.Text,analyzer = "ik_max_word",searchAnalyzer = "ik_smart")
    private String title;
}

设置Repository接口

// 定义处理的实体类是DiscussPost,实体的主键类型Integer
@Repository
public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost,Integer> {
}

2. 实现数据同步

通过生产者消费者的方式同步数据的变化,将数据保存在es服务器中
触发发帖事件。

//触发发帖事件
        Event event=new Event()
                .setTopic(TOPIC_PUBLISH)
                .setUserId(user.getId())
                .setEntityType(ENTITY_TYPE_POST)
                .setEntityId(discussPost.getId())
                ;
        eventProducer.fireEvent(event);

消费发帖事件

Event event=JSONObject.parseObject(record.value().toString(),Event.class);
// 查找新增的帖子,并保存到es
DiscussPost post= discussPostService.findDiscussPostById(event.getEntityId());
elasticSearchService.saveDiscussPost(post);

3. es搜索并分页、高亮的功能

public Page<DiscussPost> searchDiscussPost(String keyword,int current,int limit){
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery(keyword, "title", "content"))
                .withSort(SortBuilders.fieldSort("type").order(SortOrder.DESC))
                .withSort(SortBuilders.fieldSort("score").order(SortOrder.DESC))
                .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
                .withPageable(PageRequest.of(current, limit))
                .withHighlightFields(
                        new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
                        new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")
                ).build();

        return elasticsearchTemplate.queryForPage(searchQuery, DiscussPost.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass, Pageable pageable) {
                SearchHits hits = response.getHits();
                if (hits.getTotalHits() <= 0) {
                    return null;
                }

                List<DiscussPost> list = new ArrayList<>();
                for (SearchHit hit : hits) {
                    DiscussPost post = new DiscussPost();

                    String id = hit.getSourceAsMap().get("id").toString();
                    post.setId(Integer.valueOf(id));

                    String userId = hit.getSourceAsMap().get("userId").toString();
                    post.setUserId(Integer.valueOf(userId));

                    String title = hit.getSourceAsMap().get("title").toString();
                    post.setTitle(title);

                    String content = hit.getSourceAsMap().get("content").toString();
                    post.setContent(content);

                    String status = hit.getSourceAsMap().get("status").toString();
                    post.setStatus(Integer.valueOf(status));

                    String createTime = hit.getSourceAsMap().get("createTime").toString();
                    post.setCreateTime(new Date(Long.valueOf(createTime)));

                    String commentCount = hit.getSourceAsMap().get("commentCount").toString();
                    post.setCommentCount(Integer.valueOf(commentCount));

                    // 处理高亮显示的结果
                    HighlightField titleField = hit.getHighlightFields().get("title");
                    if (titleField != null) {
                        post.setTitle(titleField.getFragments()[0].toString());
                    }

                    HighlightField contentField = hit.getHighlightFields().get("content");
                    if (contentField != null) {
                        post.setContent(contentField.getFragments()[0].toString());
                    }

                    list.add(post);
                }

                return new AggregatedPageImpl(list, pageable,
                        hits.getTotalHits(), response.getAggregations(), response.getScrollId(), hits.getMaxScore());
            }
        });

4. 实现搜索功能

org.springframework.data.domain.Page<DiscussPost> searchResult= 
elasticSearchService.searchDiscussPost(keyword, page.getCurrent()-1, page.getLimit());
// 聚合数据发送到前端
List<Map<String,Object>> discussPosts=new ArrayList<>();
...

Quarzt

任务调度

在这里插入图片描述
存到数据库中
配置
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【SSCI稀缺版面】最快录用仅2个月(内附录用发表时间节点)

录用案例 JCR4区经济管理类SSCI (进展顺) 【期刊简介】IF&#xff1a;0-1.0&#xff0c;JCR4区&#xff0c;中科院4区&#xff1b; 【检索情况】SSCI在检&#xff1b; 【征稿领域】计算机/数据建模在经济与管理决策绩效评价的形态应用相关研究均可&#xff1b; 【案例分享】…

​项目文章 | METTL3敲减通过m6A-YTHDC2介导的AMIGO2调控抑制RA-FLS活化

类风湿性关节炎&#xff08;RA&#xff09;是一种自身免疫性关节疾病&#xff0c;其特征是慢性关节滑膜炎、滑膜增生过度和关节损伤。近年来&#xff0c;N6-甲基腺苷&#xff08;m6A&#xff09;修饰的RNA在癌症和自身免疫疾病&#xff08;包括RA&#xff09;中的调控作用受到广…

戏说c第二十六篇: 测试完备性衡量(代码覆盖率)

前言 师弟&#xff1a;“师兄&#xff0c;我又被鄙视了。说我的系统太差&#xff0c;测试不过关。” 我&#xff1a;“怎么说&#xff1f;” 师弟&#xff1a;“每次发布版本给程夏&#xff0c;都被她发现一些bug&#xff0c;太丢人了。师兄&#xff0c;有什么方法来衡量测试的…

VR数字化线上展馆降低企业投入成本和周期

VR云展会是一种全新的展览形式&#xff0c;它利用虚拟现实技术&#xff0c;将实体展览搬到线上&#xff0c;让观众可以在家中就能参观各种展览。这种新型的展览方式有许多亮点&#xff0c;下面就来详细介绍一下。 首先&#xff0c;VR云展会打破了地域限制。传统的实体展览通常只…

Python科学计算之生成数据

文章目录 生成序列创建网格创建特殊数组随机数组 Python科学计算系列&#xff1a;数组 正所谓巧妇难为无米之炊&#xff0c;没有数据&#xff0c;也就没法对数据进行分析&#xff0c;从而数值计算也就成了无根之木了。所以&#xff0c;在学习具体的数值计算方法之前&#xff0…

【算法 高级数据结构】树状数组:一种高效的数据结构(一)

&#x1f680;个人主页&#xff1a;为梦而生~ 关注我一起学习吧&#xff01; &#x1f4a1;专栏&#xff1a;算法题、 基础算法~赶紧来学算法吧 &#x1f4a1;往期推荐&#xff1a; 【算法基础 & 数学】快速幂求逆元&#xff08;逆元、扩展欧几里得定理、小费马定理&#x…

【详识C语言】自定义类型之一:结构体

本文重点 结构体 结构体类型的声明 结构的自引用 结构体变量的定义和初始化 结构体内存对齐 结构体传参 结构体实现位段&#xff08;位段的填充&可移植性&#xff09; 结构体 结构体的声明 结构的基础知识 结构是一些值的集合&#xff0c;这些值称为成员变量。结构的每个…

21、状态模式(行为性模式)

版本一、get状态指针 #include <iostream> using namespace std;//前置声明 class Context;//状态 class State{ public://4个状态virtual void toUp (Context& context){ }virtual void toDown (Context& context){ }virtual void toLeft (Context& cont…

Linux报错排查-刚安装好的ubuntu系统无法ssh连接

Linux运维工具-ywtool 目录 一.问题描述二.问题解决2.1 先给ubuntu系统配置阿里云源2.2 安装openssh-server软件2.3 在尝试ssh连接,可以连接成功了 三.其他命令 一.问题描述 系统:ubuntu-18.04-desktop-amd64 系统安装完后,想要通过xshell软件连接系统,发现能Ping通系统的IP,但…

视频水印怎么轻松去除?这三款神器让您直呼过瘾!

在现代社会&#xff0c;视频内容日益丰富多样&#xff0c;但有时我们更希望获得视频中的文字文稿&#xff0c;以便于搜索、编辑或传播。下面我将为您介绍三款优秀的视频转文字工具&#xff0c;它们能够帮助您快速、准确地将视频内容转换为可编辑的文字格式。让我们一起来看看这…

STM32的启动流程分析 和 一些底层控制的原理

阅读引言&#xff1a; 阅读本文之后&#xff0c; 你将对单片机&#xff0c; 甚至是嵌入式系统&#xff0c; 或者是传统的PC机系统的启动流程有一个大致的了解&#xff0c; 本文更加偏向于单片机的启动流程分析。 目录 一、基础知识 1.STM32系列的微控制器&#xff08;mcu&…

【打工日常】使用docker部署IT运维管理平台CAT

​一、CAT介绍 CAT是一个专为 IT 运维从业者打造的一站式解决方案平台&#xff0c;包含资产管理、工单、工作流、仓储等功能模块。 本项目是celaraze/chemex重构版&#xff0c;原项目chemex名称弃用&#xff1b;CAT采用全新架构设计&#xff0c;大量提升使用体验的细节&#xf…

拼多多1000元虚拟店铺免4万保证金

众所周知拼多多现在流量非常大&#xff0c;虚拟也算是蓝海&#xff0c;想做的人大部分都被保证金拦在门外&#xff0c;高达4W的保证金不是每个人都能承受的&#xff0c;正好在当下有一个方法可以解决这个苦恼。 拼多多虚拟店铺免保证金玩法现在处于前期阶段&#xff0c;很多人…

付强:基于注意力机制的听觉前端处理 | 嘉宾公布

一、智能家居与会议系统专题论坛 智能家居与会议系统专题论坛将于3月28日同期举办&#xff01; 智能会议系统它通过先进的技术手段&#xff0c;提高了会议效率&#xff0c;降低了沟通成本&#xff0c;提升了参会者的会议体验。对于现代企业、政府机构和学术界是不可或缺的。在这…

5款免费且出色的ai智能ppt制作软件,值得拥有!

如果说2023是AI崛起的元年&#xff0c;那2024无疑是AI应用的真正元年&#xff0c;人们对AI技术逐渐回归理性&#xff0c;关注的焦点也从产品层转向应用层&#xff0c;探索AI如何更好地赋能业务&#xff0c;或是重塑工作流程&#xff0c;让AI真正为自己所用。 在数字化盛兴的当…

如何利用生成式人工智能助力短视频剧本创作?

短视频已成为现代人获取娱乐和信息的一种流行方式。不同于传统的电影和电视剧&#xff0c;短视频的时长通常较短&#xff0c;内容形式多样&#xff0c;更适合快节奏的社会生活。本文将讨论如何编写短视频剧本&#xff0c;以及它与传统故事在结构和内容上的区别。 简介 短视频剧…

docker拉取镜像失败的解决方案大全

更换国内源 创建或修改 /etc/docker/daemon.json 文件&#xff0c;修改&#xff1a; {"registry-mirrors" : ["https://registry.docker-cn.com","http://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn","https:…

图文并茂的讲清楚Linux零拷贝技术

今天我们来聊一聊Linux零拷贝技术&#xff0c;今天我们以一个比较有代表性的技术sendfile系统调用为切入点&#xff0c;详细介绍一下零拷贝技术的原理。 1.零拷贝技术简介 Linux零拷贝技术是一种优化数据传输的技术&#xff0c;它可以减少数据在内核态和用户态之间的拷贝次数&…

c8t6,hal库,pwm输出

1.cubemx配置 设置分配系数&#xff1a;71&#xff1b; 自动重装在计数值&#xff1a;499&#xff1b; 72MHZ/(711) 1MHZ&#xff1b; 1MHZ即1秒计数1000000次&#xff1b; 即1毫秒计数1000次&#xff1b; 自动重装载计数值设置为499&#xff1b;即0.5ms一个周期&#xff…

新方法简单无成本申请网易云/腾讯音乐人

外面接单申请的音乐人是原创音乐人&#xff0c;通过这个方法申请的只是翻唱音乐人 如果你不想通过音乐平台赚钱的话&#xff0c;其实这两个音乐人都没什么区别 无非就是原创音乐人多了个作词、作曲的标签 翻唱音乐人一样可以领酷狗会员 音乐人特权&#xff1a; 酷狗音乐人…