某馬點評——day04

達人探店

發布探店筆記

?改一下,圖片保存路徑就可以直接運行測試了。

查看探店筆記

@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IBlogService {@Resourceprivate IUserService userService;@Overridepublic Result queryBlogById(Long id) {//1.查詢blogBlog blog = getById(id);if(blog==null){return Result.fail("筆記不存在");}//2.查詢blog有關用戶queryBlogUser(blog);return Result.ok(blog);}private void queryBlogUser(Blog blog) {Long userId = blog.getUserId();User user = userService.getById(userId);blog.setName(user.getNickName());blog.setIcon(user.getIcon());}@Overridepublic Result queryHotBlog(Integer current) {// 根據用戶查詢Page<Blog> page = query().orderByDesc("liked").page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));// 獲取當前頁數據List<Blog> records = page.getRecords();// 查詢用戶records.forEach(this::queryBlogUser);return Result.ok(records);}
}

點贊

@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IBlogService {@Resourceprivate IUserService userService;@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result queryBlogById(Long id) {//1.查詢blogBlog blog = getById(id);if(blog==null){return Result.fail("筆記不存在");}//2.查詢blog有關用戶queryBlogUser(blog);//3.查詢blog是否被點贊isBlogLiked(blog);return Result.ok(blog);}private void isBlogLiked(Blog blog) {//1.判獲取登錄用戶Long userId = UserHolder.getUser().getId();//2.判斷當前登錄用戶是否已經點贊String key=BLOG_LIKED_KEY+blog.getId();Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, userId.toString());blog.setIsLike(BooleanUtil.isTrue(isMember));}private void queryBlogUser(Blog blog) {Long userId = blog.getUserId();User user = userService.getById(userId);blog.setName(user.getNickName());blog.setIcon(user.getIcon());}@Overridepublic Result queryHotBlog(Integer current) {// 根據用戶查詢Page<Blog> page = query().orderByDesc("liked").page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));// 獲取當前頁數據List<Blog> records = page.getRecords();// 查詢用戶records.forEach(blog->{this.queryBlogUser(blog);this.isBlogLiked(blog);});return Result.ok(records);}@Overridepublic Result likeBlog(Long id) {//1.判獲取登錄用戶Long userId = UserHolder.getUser().getId();//2.判斷當前登錄用戶是否已經點贊String key=BLOG_LIKED_KEY+id;Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, userId.toString());if(BooleanUtil.isFalse(isMember)) {//3.如果未點贊//3.1數據庫點贊數+1boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update();//3.2保存用戶到Redis的set集合if(isSuccess){stringRedisTemplate.opsForSet().add(key,userId.toString());}}else {//4.如果已點贊,取消點贊//4.1數據庫點贊數-1boolean isSuccess = update().setSql("liked = liked - 1").eq("id", id).update();//4.2把用戶從redis的set集合刪除stringRedisTemplate.opsForSet().remove(key,userId.toString());}return Result.ok();}
}

點贊排行榜

?為了將最早點贊的人擺在最前面,需要按照時間先后存儲分數,這里使用zset存儲時間戳作為zset的score作為排序的依據。

然后針對mysql的排序會亂序的問題需要自定義排序規則,將數據按照指定順序展示.

@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IBlogService {@Resourceprivate IUserService userService;@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result queryBlogById(Long id) {//1.查詢blogBlog blog = getById(id);if(blog==null){return Result.fail("筆記不存在");}//2.查詢blog有關用戶queryBlogUser(blog);//3.查詢blog是否被點贊isBlogLiked(blog);return Result.ok(blog);}private void isBlogLiked(Blog blog) {//1.判獲取登錄用戶UserDTO user = UserHolder.getUser();if(user==null){//用戶未登錄,無需查詢是否點贊return;}Long userId = user.getId();//2.判斷當前登錄用戶是否已經點贊String key=BLOG_LIKED_KEY+blog.getId();Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());blog.setIsLike(score!=null);}private void queryBlogUser(Blog blog) {Long userId = blog.getUserId();User user = userService.getById(userId);blog.setName(user.getNickName());blog.setIcon(user.getIcon());}@Overridepublic Result queryHotBlog(Integer current) {// 根據用戶查詢Page<Blog> page = query().orderByDesc("liked").page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));// 獲取當前頁數據List<Blog> records = page.getRecords();// 查詢用戶records.forEach(blog->{this.queryBlogUser(blog);this.isBlogLiked(blog);});return Result.ok(records);}@Overridepublic Result likeBlog(Long id) {//1.判獲取登錄用戶Long userId = UserHolder.getUser().getId();//2.判斷當前登錄用戶是否已經點贊String key=BLOG_LIKED_KEY+id;Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());if(score==null) {//3.如果未點贊//3.1數據庫點贊數+1boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update();//3.2保存用戶到Redis的set集合 zadd key value scoreif(isSuccess){stringRedisTemplate.opsForZSet().add(key,userId.toString(),System.currentTimeMillis());}}else {//4.如果已點贊,取消點贊//4.1數據庫點贊數-1boolean isSuccess = update().setSql("liked = liked - 1").eq("id", id).update();//4.2把用戶從redis的set集合刪除stringRedisTemplate.opsForZSet().remove(key,userId.toString());}return Result.ok();}@Overridepublic Result queryBlogLikes(Long id) {//1.查詢top5的點贊用戶 zrange key 0 4String key=BLOG_LIKED_KEY+id;Set<String> top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4);if(top5==null||top5.isEmpty()){return Result.ok(Collections.emptyList());}//2.解析出用戶idList<Long> ids = top5.stream().map(Long::valueOf).collect(Collectors.toList());//將id拼成字符串String idStr = StrUtil.join(",", ids);//3.根絕用戶id查詢用戶 必須自定義排序規則進行查詢,否則原本是有序的數據查完之后就變成無序的了List<UserDTO> userDTOS = userService.query().in("id",ids).last("ORDER BY FIELD(id,"+idStr+")").list().stream().map(user -> BeanUtil.copyProperties(user, UserDTO.class)).collect(Collectors.toList());//4.返回return Result.ok(userDTOS);}
}

好友關注

關注和取關

一個接口實現關注和取關

@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow> implements IFollowService {/*** 關注取關功能* @param followUserId* @param isFollow* @return*/@Overridepublic Result follow(Long followUserId, Boolean isFollow) {//1.獲取登錄用戶Long userId = UserHolder.getUser().getId();//1.判斷到底是關注還是取關if (isFollow) {//2.關注,新增數據Follow follow = new Follow();follow.setUserId(userId);follow.setFollowUserId(followUserId);save(follow);}else{//3.取關,刪除 delete from tb_follow where userId = ? and follow_user_id = ?remove(new QueryWrapper<Follow>().eq("user_id",userId).eq("follow_user_id",followUserId));}return Result.ok();}@Overridepublic Result isFollow(Long followUserId) {//1.獲取登錄用戶Long userId = UserHolder.getUser().getId();//2.查詢是否關注 select count(*)  from tb_follow where userId = ? and follow_user_id = ?Integer count = query().eq("user_id", userId).eq("follow_user_id", followUserId).count();//3.判斷return Result.ok(count>0);}
}

共同關注

這兩個接口直接使用資料里的代碼片段

// UserController 根據id查詢用戶@GetMapping("/{id}")
public Result queryUserById(@PathVariable("id") Long userId){// 查詢詳情User user = userService.getById(userId);if (user == null) {return Result.ok();}UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);// 返回return Result.ok(userDTO);
}// BlogController
@GetMapping("/of/user")
public Result queryBlogByUserId(@RequestParam(value = "current", defaultValue = "1") Integer current,@RequestParam("id") Long id) {// 根據用戶查詢Page<Blog> page = blogService.query().eq("user_id", id).page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));// 獲取當前頁數據List<Blog> records = page.getRecords();return Result.ok(records);
}

?為了能用redis的set集合取交集求得共同關注的好友,這里要將一個用戶關注的所有人都存儲到redis里的set集合,,取關了從set集合里刪除。

代碼實現

    @Overridepublic Result followCommons(Long id) {//1.獲取當前用戶Long userId = UserHolder.getUser().getId();String key="follows:"+userId;//2.求交集String key2="follows:"+id;Set<String> intersect = stringRedisTemplate.opsForSet().intersect(key, key2);if(intersect==null||intersect.isEmpty()){//無交集return Result.ok(Collections.emptyList());}//3.解析id集合List<Long> ids = intersect.stream().map(Long::valueOf).collect(Collectors.toList());//4.查詢用戶List<UserDTO> users = userService.listByIds(ids).stream().map(user -> BeanUtil.copyProperties(user, UserDTO.class)).collect(Collectors.toList());return Result.ok(users);}

關注推送

有點像觀察者模式,觀察者給監聽者集體發送消息。

?feed流實現方案分析?

拉模式下會將用戶關注的人的消息全都拉取到收件箱里面按照時間進行排序。?這個模式下,消息只會在作者的發件箱持久保存一份,用戶的收件箱每次打開都會去拉取一份新的,用完就刪。每次都讀取一堆,性能消耗大。

?推模式下會將消息發送到用戶的收件箱持久化保存。但是這個模式下一個消息會寫n份,內存占用高。

普通v直接用推模式,大v的活躍粉絲用推模式,普通粉絲數量多用拉模式。?

?基于推模式實現關注推送功能

這里選擇推送blog的id到用戶的收件箱,用戶要看時再現查。

這里使用Redis的Zset進行保存,基于時間戳進行排序,要進行分頁查詢時利用角標0~n。

這里傳統分頁好像是有個問題,會出現相同商品重復出現的情況。然后利用滾動分頁就不會有這種情況,但是這樣話新數據又去哪里了??

?

使用sortedSet實現的時候,每次分頁記住時間戳最小的那個,下次查就從更小的開始,就不會出現數據重復了。

推送代碼實現

改造新增blog的代碼,在新增成功的時候獲取所有粉絲id進行blog推送。

    @Overridepublic Result saveBlog(Blog blog) {// 1.獲取登錄用戶UserDTO user = UserHolder.getUser();blog.setUserId(user.getId());// 2.保存探店博文boolean isSucess = save(blog);if(!isSucess){return Result.fail("新增筆記失敗");}//3.查詢筆記作者的所有粉絲 select * from tb_follow where follow_user_id=?List<Follow> follows = followService.query().eq("follow_user_id", user.getId()).list();//4.推送筆記id給所有粉絲for(Follow follow:follows){//4.1獲取粉絲idLong userId = follow.getUserId();//4.2推送String key=FEED_KEY+userId;stringRedisTemplate.opsForZSet().add(key,blog.getId().toString(),System.currentTimeMillis());}// 3.返回idreturn Result.ok(blog.getId());}
滾動分頁查詢收件箱思路

使用的是zrange,不能按照角標查詢,要按照score進行查詢.

所以這里使用按照分數查詢的命令.?但是這里也會存在問題,如果存在兩個相同score的話,可能也會出現重復,因為命令是按照小于等于。

滾動分頁查詢實現?

這個代碼好像還是有點問題,這里查詢了blog有關用戶和是否點贊卻沒有用上

@Data
public class ScrollResult {private List<?> list;private Long minTime;private Integer offset;
}
    @GetMapping("/of/follow")public Result queryBlogOfFollow(@RequestParam("lastId") Long max, @RequestParam(value = "offset",defaultValue = "0") Integer offset){return blogService.queryBlogOfFollow(max,offset);}
    @Overridepublic Result queryBlogOfFollow(Long max, Integer offset) {//1.獲取當前用戶Long userId = UserHolder.getUser().getId();//2.查詢收件箱 ZREVRANGBYSCORE key MAX MIN WITHSCORES LIMIT offset countString key=FEED_KEY+userId;Set<ZSetOperations.TypedTuple<String>> typedTuples = stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, 0, max, offset, 2);//3.非空判斷if(typedTuples==null||typedTuples.isEmpty()){return Result.ok();}//4.解析數據: blogId ,mintime(時間戳),offsetList<Long> ids=new ArrayList<>(typedTuples.size());long minTime=0;int os=1;for (ZSetOperations.TypedTuple<String> tuple : typedTuples) { ////4.1獲取idids.add(Long.valueOf(tuple.getValue()));//4.2獲取分數(時間戳)long time=tuple.getScore().longValue();if(time==minTime){os++;}else{minTime=time;os=1;}}//5.根據id查詢blog 基于in語句查詢會打亂順序String idStr = StrUtil.join(",", ids);List<Blog> blogs =query().in("id",ids).last("ORDER BY FIELD(id,"+idStr+")").list();for (Blog blog : blogs) {//5.1.查詢blog有關的用戶queryBlogUser(blog);//5.2.查詢blog是否被點贊isBlogLiked(blog);}//6.封裝并返回ScrollResult scrollResult = new ScrollResult();scrollResult.setList(blogs);scrollResult.setMinTime(minTime);scrollResult.setOffset(os);return Result.ok(scrollResult);}

附近商鋪

GEO數據結構的基本用法

?

導入店鋪數據到GEO

寫一個數據導入的測試類

?

    @Testvoid loadShopDate(){//1.查詢店鋪信息List<Shop> list = shopService.list();//2.把店鋪分組,按照typeId分組,typeId一致的放到一個集合Map<Long,List<Shop>>  map=list.stream().collect(Collectors.groupingBy(Shop::getTypeId));//3.分批完成寫入Redisfor (Map.Entry<Long, List<Shop>> entry : map.entrySet()) {//3.1獲取類型idLong typeId = entry.getKey();String key= SHOP_GEO_KEY+typeId;//3.2獲取同類型的店鋪的集合List<Shop> value = entry.getValue();List<RedisGeoCommands.GeoLocation<String>> locations=new ArrayList<>();//3.3寫入redis geoadd key 經度 維度 memberfor (Shop shop : value) {//寫入一條數據//stringRedisTemplate.opsForGeo().add(key,new Point(shop.getX(),shop.getY()),shop.getId().toString());locations.add(new RedisGeoCommands.GeoLocation<>(shop.getId().toString(),new Point(shop.getX(),shop.getY())));}//一次寫入多條數據stringRedisTemplate.opsForGeo().add(key,locations);}}

實現附近商戶功能

用戶簽到

BitMap功能演示?

這個表格里的每一行數據就是用戶的一條簽到記錄,現在使用二進制壓縮來存儲.

實現簽到功能

?代碼實現

    @Overridepublic Result sign() {//1.獲取當前登錄用戶Long userId = UserHolder.getUser().getId();//2.獲取日期LocalDateTime now = LocalDateTime.now();//3.拼接keyString keySuffix = now.format(DateTimeFormatter.ofPattern("yyyyMM"));String key=USER_SIGN_KEY+userId+keySuffix;//4.獲取今天是本月的第幾天int dayOfMonth = now.getDayOfMonth();//5.寫入Redis SETBIT key offset 1stringRedisTemplate.opsForValue().setBit(key, dayOfMonth-1,true);return Result.ok();}

統計連續簽到

代碼實現

@Overridepublic Result signCount() {//1.獲取當前登錄用戶Long userId = UserHolder.getUser().getId();//2.獲取日期LocalDateTime now = LocalDateTime.now();//3.拼接keyString keySuffix = now.format(DateTimeFormatter.ofPattern("yyyyMM"));String key=USER_SIGN_KEY+userId+keySuffix;//4.獲取今天是本月的第幾天int dayOfMonth = now.getDayOfMonth();//5.獲取本月截止今天為止的所有的簽到記錄,要返回的是一個十進制的數字 BITFIELD sign:8:202312 GET u14 0List<Long> result = stringRedisTemplate.opsForValue().bitField(key,BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0) //今天多少號就多少個bit位);if(result==null||result.isEmpty()){//沒有任何簽到結果return Result.ok(0);}Long num=result.get(0);if(num==null||num==0){return Result.ok(0);}//6.循環遍歷int count=0;while(true){//6.1讓這個數字與1做與運算,得到數字的最后一個bit位//判斷這個bit位是否為0if ((num&1)==0) {//如果為0,說明未簽到,結束break;}else{//如果不為0,說明已簽到,計數器+1count++;}//把數字右移一位,拋棄最后一個bit位,繼續下一個bit位num>>>=1;}return Result.ok(count);}

UV統計

HyperLogLog的用法

?

測試百萬數據的統計

    @Testvoid testHyperLogLog(){//準備數組,裝用戶數據String[] users = new String[1000];//數據角標記int index=0;for(int i=1;i<=1000000;i++){//賦值users[index++]="user_"+i;//每1000條發送一次if(i%1000==0){index=0;stringRedisTemplate.opsForHyperLogLog().add("hl2",users);}}//統計數量Long hl2 = stringRedisTemplate.opsForHyperLogLog().size("hl2");System.out.println(hl2);}

這個測試方法一直運行失敗,我真的吐了.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/208846.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/208846.shtml
英文地址,請注明出處:http://en.pswp.cn/news/208846.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenCL學習筆記(二)手動編譯開發庫(win10+vs2019)

前言 有時需求比較特別&#xff0c;可能需要重新編譯opencl的sdk庫。本文檔簡單記錄下win10下&#xff0c;使用vs2019編譯的過程&#xff0c;有需要的小伙伴可以參考下 一、獲取源碼 項目地址&#xff1a;GitHub - KhronosGroup/OpenCL-SDK: OpenCL SDK 可以直接使用git命令…

一篇文章了解指針變量

字符指針變量 在指針的類型中我們知道有一種指針叫做字符指針 它的使用情況如下&#xff1a; #include<stdio.h> int main() {char pa w;char*p1&pa;*p1 a;printf("%c\n", *p1);return 0; } 在這段代碼當中&#xff0c;我們將‘w’字符的地址傳到了p…

vue3 自己寫一個月的日歷

效果圖 代碼 <template><div class"monthPage"><div class"calendar" v-loading"loading"><!-- 星期 --><div class"weekBox"><div v-for"(item, index) in dayArr" :key"index&q…

2.修改列名與列的數據類型

修改字段名與字段數據類型 1.修改字段名 有時&#xff0c;在我們建好一張表后會突然發現&#xff0c;哎呀&#xff01;字段名貌似寫錯了&#xff01;怎么辦&#xff1f;要刪了表再重新建一個新表嗎&#xff1f;還是要刪了這個字段再新建一個新的字段&#xff1f; 都不用&…

AIGC專題報告:生成式人工智能人人可用的新時代

今天分享的AIGC系列深度研究報告&#xff1a;《AIGC專題報告&#xff1a;生成式人工智能人人可用的新時代》。 &#xff08;報告出品方&#xff1a;埃森哲&#xff09; 報告共計&#xff1a;21頁 人工智能發展迎來新拐點 ChatGPT 正在喚醒全球對人工智能&#xff08;AI&…

蛇形矩陣

蛇形矩陣是由1開始的自然數依次排列成的一個矩陣上三角形。 例如&#xff0c;當輸入5時&#xff0c;應該輸出的三角形為&#xff1a; 1 3 6 10 15 2 5 9 14 4 8 13 7 12 11 輸入描述&#xff1a;輸入正整數N&#xff08;N不大于100&#xff09; 輸出描述&#xff1a;輸出一個N…

MySQL七 | 存儲引擎

目錄 存儲引擎 存儲引擎特點 存儲引擎選擇 Innodb與MyISAM區別 存儲引擎 默認存儲引擎:InnoDB show engines;#展示當前數據庫支持的存儲引擎 存儲引擎特點 特點InnoDBMyISAMMemory存儲限制64TB有有事務安全支持--鎖機制行鎖表鎖表鎖Btree鎖支持支持 支持 Hash索引--支…

在pom.xml中添加maven依賴,但是類里面import導入的時候報錯

問題&#xff1a; Error:(27, 8) java: 類TestKuDo是公共的, 應在名為 TestKuDo.java 的文件中聲明 Error:(7, 23) java: 程序包org.apache.kudu不存在 Error:(8, 23) java: 程序包org.apache.kudu不存在 Error:(9, 23) java: 程序包org.apache.kudu不存在 Error:(10, 30) jav…

【場景測試用例】上傳文件

測試思路&#xff1a; 功能 上傳符合需求給的文件格式&#xff0c;大小&#xff0c;寬高等可以正常上傳 不同的文件格式最大/最小/中間的文件大小如支持批量上傳可以正常上傳 邊界值如支持刪除可以正常刪除指定文件&#xff0c;其他文件不受影響如支持預覽&#xff0c;可以正常…

【Java探索之旅】我與Java的初相識(一):Java的特性與優點及其發展史

&#x1f3a5; 嶼小夏 &#xff1a; 個人主頁 &#x1f525;個人專欄 &#xff1a; Java入門到精通 &#x1f304; 莫道桑榆晚&#xff0c;為霞尚滿天&#xff01; 文章目錄 一. Java語言概述與優勢1.1 Java的概述1.2 Java語言的優勢 二. Java領域與發展史2.1 Java的使用領域2.…

面試多線程八股文十問十答第二期

面試多線程八股文十問十答第二期 作者&#xff1a;程序員小白條&#xff0c;個人博客 相信看了本文后&#xff0c;對你的面試是有一定幫助的&#xff01; ?點贊?收藏?不迷路&#xff01;? 1.進程和線程的區別 概念不同&#xff1a;進程是操作系統中的一個獨立執行單元&a…

LeetCode56. Merge Intervals

文章目錄 一、題目二、題解 一、題目 Given an array of intervals where intervals[i] [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input. Example 1: Input: interva…

目標檢測mAP計算以及coco評價標準

這篇是我對嗶哩嗶哩up主 霹靂吧啦Wz 的視頻的文字版學習筆記 感謝他對知識的分享 講一下目標檢測中的一些常見的指標 在我們使用目標檢測網絡訓練時 最后在驗證集上會得到一個coco的評價列表 就像我們圖中給的這一系列參數列表一樣 我們再進一步引入兩個概念 第一個叫做precisi…

P1 Qt的認識及環境配置

目錄 前言 01 下載Qt Creator windows下載安裝包拷貝到Linux Linux直接下載 02 Linux 安裝Qt 前言 &#x1f3ac; 個人主頁&#xff1a;ChenPi &#x1f43b;推薦專欄1: 《C_ChenPi的博客-CSDN博客》??? &#x1f525; 推薦專欄2: 《Linux C應用編程&#xff08;概念類…

地址欄不安全提示

在使用瀏覽器時訪問網站的時候&#xff0c;我們可能會遇到地址欄提示不安全的情況。這種情況通常都是是由于未安裝有效SSL證書或者網站SSL證書過期等原因導致的。本文將介紹如何處理地址欄提示不安全的問題&#xff0c;以確保我們的上網安全。 1&#xff0c;缺少SSL證書&#x…

golang游戲服務器 - tgf系列課程01

TGF框架的特點和功能 課程介紹了TGF框架的特點和功能在第一節課程中我們并不會介紹框架的使用。我們希望在這節課程中,能讓你了解到tgf是一個什么樣的框架 概要 本節課程介紹了TGF框架的特點和功能。TGF是一個開箱即用的服務器框架, 適合中小型團隊和獨立開發者進行游戲開發。…

基于單片機音樂盒仿真仿真系統設計

**單片機設計介紹&#xff0c;基于單片機音樂盒仿真仿真系統設計 文章目錄 一 概要二、功能設計設計思路 三、 軟件設計原理圖 五、 程序六、 文章目錄 一 概要 基于單片機的音樂盒仿真仿真系統是一種基于嵌入式系統技術的設計方案&#xff0c;用于模擬傳統的音樂盒功能。它通…

002 self-attention自注意力

目錄 一、環境 二、self-attention原理 三、完整代碼 一、環境 本文使用環境為&#xff1a; Windows10Python 3.9.17torch 1.13.1cu117torchvision 0.14.1cu117 二、self-attention原理 自注意力&#xff08;Self-Attention&#xff09;操作是基于 Transformer 的機器翻…

【XILINX】記錄ISE/Vivado使用過程中遇到的一些warning及解決方案

前言 XILINX/AMD是大家常用的FPGA&#xff0c;但是在使用其開發工具ISE/Vivado時免不了會遇到很多warning&#xff0c;(大家是不是發現程序越大warning越多&#xff1f;)&#xff0c;并且還有很多warning根據消除不了&#xff0c;看著特心煩&#xff1f; 我這里匯總一些我遇到的…

http和https區別

http和https區別 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是用于在網絡上傳輸數據的兩種協議。它們之間的主要區別在于安全性和數據傳輸方式&#xff1a; 安全性&#xff1a;HTTP是明文傳…