记录 | 大学里的最后一段时光 #日记楼

日志 / 部落格 blog 3247 views 309 replies
#1 ·

Vanitas Vanitatum Et Omnia Vanitas.

虚空的虚空,一切尽为虚空。《般若波罗蜜多心经》亦有言:“观自在菩萨,行深般若波罗蜜多时,照见五蕴皆空,度一切苦厄”。

古今中外,英雄豪杰无不如过江之鲫,于兴盛之时,凭天时地利人和,独领风骚,傲立潮头。殊不知千年之后,虽有“樯橹灰飞烟灭”之气魄,亦不免消失于滚滚历史洪流。

泛泛之辈如我,唯有专注于当下,珍惜自我所有之物,珍惜身边亲近的人,默默地走完本科的最后一段旅程。2025 年 06 月至 2026 年 06 月,我愿在此处不定期地记录下属于自己的一切。

一切皆空,唯有当下愈加贵重。万事喧嚣,愿有一方清静独处之处。愿此处小楼能成为承载我接下来一年的喜怒哀乐,愿自己能够在互联网的一角,留下属于自己的一点点痕迹。

开楼就用我最喜欢的一部动画《可塑性记忆 (プラスチックメモリス)》中的题词送给大家,也送给自己:

愿你有朝一日,能与珍爱之人再次相逢大切な人と、いつかまた巡り会えますように

image|690x388

提示:可能有时候 lz 会有很负面的情绪,或者不恰当的表述,先向大家表示抱歉,如果楼主说了什么不太好的话或者令大家伤心的话,提示一下 lz 或者屏蔽楼主就好了,先向大家表示歉意,对不起,谢谢大家 🥰

楼里会有什么?

  • 可愛いアイラちゃん
  • 各种可能的动漫截图
  • 每天的生活
  • 风景图?周边地图?
  • 🐷 😋 🤡
  • lz 的焦虑和不安 (很抱歉,有时候控制不了自己 🥲)
  • 可能的焦虑传播 (对不起,请一定要提醒 lz 删除(私信发帖都可以))
  • 可能的压力和不安
❤️🤗️🥰️
16
#2 · (edited)

cy :tieba_huanhu:
是新日记楼!
祝 lz 生活顺利🥹

长恨此身非我有 何时忘却营营

❤️
1
#3 · (edited)

开篇先给出自己的假期计划吧!
古人有云:“取法乎上,仅得其中。取法乎中,仅得其下。”所以目标要兼具挑战性和可行性。
暑假的三个月打算:
上午 7:00 左右起床
上午:leetcode,复习数据结构,与其他 408 科目,顺序打算为数据结构 -> 计算机组成 -> 操作系统 -> 计算机网络。这些科目アイラちゃん在期末都是 90 分左右,因此希望会顺利一些 QAQ,为考研/推免都做好两手准备 🫠
中午/下午:做实验室实习的项目/阅读需要阅读的论文,或者在没有活的时候做一做 15445/6.824,学习 C++/Go。毕竟有希望就要去争取!
晚上:继续复习高数/线代。等到线性代数复习结束后再开概率论和数理统计。并且最后复习一些单词(不过英语应该不需要太担心,アイラちゃん很努力地通过了 Toefl, R25L25S25W26!)
希望自己能完成这个暑假的计划,fight on!!!

❤️
2
#4 · (edited)

cy :shuiyuan3:
アイラちゃん(指插图中的艾拉)今日もちょ可愛いです 🥰

❤️
2
#5 ·

image|690x417

🥰

❤️🥰️😍️
5
#6 ·
sumire アイラちゃん

🥰 🥰
艾拉可爱捏
如果能让アイラちゃん做我的彼女我就算住大别野也愿意口牙 :bilibili_aojiao:

❤️🥰️
4
#7 · (edited)

2025 年 5 月 30 日 星期五 天气:晴/多云

上午刷 leetcode,复习了一下 dijkstra 算法,正好今天的每日一题也是 dijkstra 算法~

2359. 找到离给定两个节点最近的节点

C++
class Solution {
    int n;
public:
    void bfs(const vector<vector<int>> & graph, priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> & pq, vector<int> & distance, vector<int> & visited, const int & node) {
        visited = vector<int>(n, 0);
        pq.emplace(0, node);
        visited[node] = 1;
        distance[node] = 0;

        while(!pq.empty()) {
            const auto [dist, cur] = pq.top();
            pq.pop();
            for(const auto & adj: graph[cur]) {
                if(distance[adj] > distance[cur] + 1) {
                    distance[adj] = distance[cur] + 1;
                    pq.emplace(distance[adj], adj);
                }
            }
        }
    }
    int closestMeetingNode(vector<int>& edges, int node1, int node2) {
        n = edges.size();
        vector<vector<int>> graph(n);
        for(int i = 0; i < n; i++) {
            if(edges[i] == -1) continue;
            graph[i].emplace_back(edges[i]);
        }
        priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
        vector<int> distance1(n, INT_MAX / 2);
        vector<int> distance2(n, INT_MAX / 2);
        vector<int> visited;

        bfs(graph, pq, distance1, visited, node1);
        bfs(graph, pq, distance2, visited, node2);

        // Get the distance. Then check the answer.
        int ans_dist = INT_MAX / 2;
        int ans = -1;

        for(int i = 0; i < n; i++) {
            int tmp_ans = max(distance1[i], distance2[i]);
            if(ans_dist > tmp_ans) {
                ans_dist = tmp_ans;
                ans = i;
            }
            else if(ans_dist == tmp_ans) {
                ans = min(ans, i);
            }
        }
        return ans == INT_MAX / 2 ? -1 : ans;
    }
};

2642. 设计可以求最短路径的图类

C++
class Graph {
    vector<vector<pair<int,int>>>graph;
    vector<int> visited;
    vector<int> distance;
    int n;
public:
    Graph(int n, vector<vector<int>>& edges) {
        graph = vector<vector<pair<int,int>>>(n);
        for(const auto & edge: edges) {
            int from = edge[0], to = edge[1], edgeCost = edge[2];
            graph[from].emplace_back(to, edgeCost);
        }
        Graph::n = n;
    }
    
    void addEdge(vector<int> edge) {
        int from = edge[0], to = edge[1], edgeCost = edge[2];
        graph[from].emplace_back(to, edgeCost);
    }
    
    int shortestPath(int node1, int node2) {
        priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
        visited = vector<int>(n, 0);
        distance = vector<int>(n, INT_MAX / 2);
        pq.emplace(0, node1);
        distance[node1] = 0;
        while(!pq.empty()) {
            const auto [dist, cur] = pq.top();
            pq.pop();
            if(visited[cur]) continue;
            visited[cur] = 1;
            for(const auto & adj: graph[cur]) {
                const auto [adj_to, adj_w] = adj;
                if(distance[adj_to] > distance[cur] + adj_w) {
                    distance[adj_to] = distance[cur] + adj_w;
                    pq.emplace(distance[adj_to], adj_to);
                }
            }
        }
        return distance[node2] == INT_MAX / 2 ? -1 : distance[node2];
    }
};

/**
 * Your Graph object will be instantiated and called as such:
 * Graph* obj = new Graph(n, edges);
 * obj->addEdge(edge);
 * int param_2 = obj->shortestPath(node1,node2);
 */

3342. 到达最后一个房间的最少时间 II

C++
constexpr int directions[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
class Solution {
public:
    int minTimeToReach(vector<vector<int>>& moveTime) {
        // [dist, x, y];
        priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<tuple<int,int,int>>> pq;
        pq.emplace(0, 0, 0);
        int rows = moveTime.size(), cols = moveTime[0].size();
        vector<vector<int>> distance(rows, vector<int>(cols, INT_MAX / 2));
        vector<vector<int>> visited(rows, vector<int>(cols, 0));
        distance[0][0] = 0;

        while(!pq.empty()) {
            const auto [dist, x, y] = pq.top();
            pq.pop();
            if(visited[x][y]) continue;
            visited[x][y] = 1;
            for(int i = 0; i < 4; i++) {
                int nx = x + directions[i][0], ny = y + directions[i][1];
                if(nx >= 0 && nx < rows && ny >= 0 && ny < cols) {
                    int temp_distance = max(dist, moveTime[nx][ny]) + (x+y) % 2 + 1;
                    if(temp_distance < distance[nx][ny]) {
                        distance[nx][ny] = temp_distance;
                        pq.emplace(temp_distance, nx, ny);
                    }
                }
            }
        }
        return distance[rows - 1][cols - 1];
    }
};

跟着 灵神的题单 走感觉有进步的说!

然后折磨アイラちゃん四天只睡了 16 个小时的 PPG 算法也算是成功实现了,并且确实收敛的速度更快,只是为什么稳定性不好呢 QAQ

下午上数据库原理课,听不懂事务系统 🐷 时间戳控制事务法和 2PL 法更是稀里糊涂 🫠 后面暑假再仔细看看吧~反正不考

晚上学了一下 Go,这门语言还是很有属于自己的风范的,感觉有集百家之长的特性,希望我能稍微掌握一下吧~(这也是兴趣的一部份呢)

最后,提前祝大家晚安好梦的说! 🥰 也祝大家期末顺利!

❤️
3
#8 ·

口瓜怎么日记帖被拿下了 🥲 5 月 30 日的日记贴变成垃圾消息被 Akismet ちゃん拿下了 🥺

是不是主包发 leetcode 题目和代码重复性太高被拿下了 🫠

截屏 2025-05-30 22.28.04|690x388

❤️🤣️
4
#9 ·
sumire アイラちゃん

我们土塬貌似是这样的🤔不时会出现这种吞帖的情况
感觉可以向站务提出说明?

❤️
1
#10 · (edited)

站务应该会看到的,就不再单独麻烦他们了 🥺

akismet ちゃん好严厉,有坏坏的大姐姐感觉 🤣

#11 ·
sumire アイラちゃん

豪德 🫠

❤️
1
#12 ·

好饿,出去觅食了 🐖
好耶,帖子回来啦 🥰
谢谢站务 😘

❤️wave_gif
6
#13 · (edited)

有 C/C++ 基础看起一门新的语言还是很快的,只是迫切地需要熟练度

https://gobyexample.com/

从例子入手后再去仔细地阅读语法,希望这样能够快速入门 Go, 然后尝试 6.824

https://go.dev/doc/

p.s.现在变成 6.5840 了,待我学会 go+ 有时间后尝试一下 😋

https://pdos.csail.mit.edu/6.824/

❤️
3
#14 · (edited)

每日一题 还是可以 Dijkstra 的,毕竟 Dijkstra 就是 BFS 中的队列->优化队列而已~

909. 蛇梯棋 (2020M)(2025.05.31)

坐标变换让我成为 🐖

C++-1 (Dijkstra)
class Solution {
public:
    int n;
    int CheckTransfer(int nums, vector<vector<int>> & board) {
        int row, col;
        if(nums % n == 0) {
            row = n - nums / n;
            if(row % 2 != n % 2) {
                col = n-1;
            }
            else {
                col = 0;
            }
        } else {
            row = n - 1 - nums / n;
            if(row % 2 != n % 2) {
                col = (nums % n) - 1;
            }
            else {
                col = n - (nums % n);
            }
        }
        
        // // ** debug **
        // cout << nums << " at: (" << row << " ," << col << ")\n";
        return board[row][col]; 
    }
    int snakesAndLadders(vector<vector<int>>& board) {
        // Build Matrix.
        n = board.size();

        vector<int> distance(n*n+1, INT_MAX / 2);
        vector<int> visited(n*n+1, 0);
        priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
        pq.emplace(0,1);
        distance[1] = 0;
        while(!pq.empty()) {
            // BFS to get the adjacent point.
            const auto [dist, cur] = pq.top();
            pq.pop();
            if(visited[cur]) continue;
            visited[cur] = 1;
            for(int i = cur + 1; i <= min(cur + 6, n * n); i++) {
                int transfer = CheckTransfer(i, board);
                int adj = transfer == -1 ? i : transfer;
                if(distance[adj] > distance[cur] + 1) {
                    distance[adj] = distance[cur] + 1;
                    pq.emplace(distance[adj], adj);
                }
            }
        }
        return distance[n * n] == INT_MAX / 2 ? -1 : distance[n * n];
    }
};
C++-2 (BFS)
class Solution {
public:
    int n;
    int CheckTransfer(int nums, vector<vector<int>> & board) {
        int row, col;
        if(nums % n == 0) {
            row = n - nums / n;
            if(row % 2 != n % 2) {
                col = n-1;
            }
            else {
                col = 0;
            }
        } else {
            row = n - 1 - nums / n;
            if(row % 2 != n % 2) {
                col = (nums % n) - 1;
            }
            else {
                col = n - (nums % n);
            }
        }
        
        // // ** debug **
        // cout << nums << " at: (" << row << " ," << col << ")\n";
        return board[row][col]; 
    }
    int snakesAndLadders(vector<vector<int>>& board) {
        // Build Matrix.
        n = board.size();

        vector<int> visited(n*n+1, 0);
        queue<pair<int,int>> q;
        q.emplace(1, 0);
        while(!q.empty()) {
            // BFS to get the adjacent point.
            const auto [cur, dist] = q.front();
            q.pop();
            visited[cur] = 1;
            for(int i = cur + 1; i <= min(cur + 6, n * n); i++) {
                int transfer = CheckTransfer(i, board);
                int adj = transfer == -1 ? i : transfer;
                if(visited[adj]) continue;
                if(adj == n * n) return dist + 1;
                visited[adj] = 1;
                q.emplace(adj, dist + 1);
            }
        }
        return -1;
    }
};
成就 badges

截屏 2025-05-31 10.07.49|690x197

不知不觉三个月了,希望有点进步的说

被 xiong 器裹挟的アイラちゃん

截屏 2025-05-31 10.09.37|474x500

❤️
1
#15 ·

今天是端午节,祝塬友们端午快乐!
也祝 @萨卡兹雇佣兵 生日快乐 🥰

❤️
5
#16 ·
sumire アイラちゃん

谢谢泥喵 :cherry_blossom_cat:(话说我也谢了泥好多次了 🤪)

❤️
1
#17 · (edited)

惊觉一门课下周四有随堂考还有 40% 的分数
天塌了,我说怎么这门课没有大作业,原来是今天跟我说改成随堂考了
好好好 🥺

发挥优良传统,一支笔,一个 graffiti,一个晚上,一个奇迹 🐖

❤️
3
#18 ·
sumire アイラちゃん
アイラちゃん,post:7, topic:14653, username:sumire:

集百家之长的特性

好乐,难得见一个不骂的

❤️
1
#19 · (edited)

2025 年 5 月 31 日
今天是五月的最后一天!端午假期快乐!

アイラちゃん,post:17, topic:14653, username:sumire:

惊觉一门课下周四有随堂考还有 40% 的分数
天塌了,我说怎么这门课没有大作业,原来是今天跟我说改成随堂考了

前情提要⬆️

于是战复习,复习模型压缩,剪枝,量化策略,复习 TPU 脉动阵列模型,数据流不变方式复用比,amdahl 定理,并行加速比 😴

不过已经复习完一半了!明天就可以复习结束的说!
明天可能要下大暴雨了,真讨厌下雨啊,每次鞋都会湿完,但是还是得来图书馆的,在宿舍只想睡觉就好了 🐖

骑士团和狐狸小队的麻麻们

1746972329978|353x500

最后,祝大家晚安好梦~

❤️
7
#20 ·

口瓜,已经下雨了,怎么回事口牙

❤️
4
#21 ·
sumire アイラちゃん

上海怎么天天下雨 :tieba_rage:

❤️
3
#22 ·
萨卡兹雇佣兵 神秘小维

江淮气旋 + 梅雨=暴雨 🥲

image|604x500

明天的雨势更加猛烈 😵‍💫

image|604x500

❤️😰️
4
#23 ·

2929. 给小朋友们分糖果 II (1701M)(2025.06.01)

数学题~ 祝大家儿童节快乐 :cat_crown:

Go
func distributeCandies(n int, limit int) int64 {
	var ans int64
	ans = 0
	for i := 0; i <= min(limit, n); i++ {
		ans = ans + int64(max(int64(min(limit, n-i)) - int64(max(n-i-limit, 0))+1, 0))
	}
	return ans
}
C++
class Solution {
public:
    long long distributeCandies(int n, int limit) {
        long long ans = 0;
        for(int i = 0; i <= min(limit, n); i++) {
            ans += (long long)max(min(limit, n-i) - max(n-i-limit, 0) + 1, 0);
        }
        return ans;
    }
};
❤️
4
#24 ·
萨卡兹雇佣兵 神秘小维

正在宾馆里躲雨 :sob_mouse:

此人不语,只是一味地在门里生产废料。

❤️
4
#25 ·

上午复习完了周四的考试,实现了昨天在 神秘小维的赛博小窝 的誓言 :cat_crown:

アイラちゃん,post:459, topic:14475, full:true, username:sumire:

借你吉言,明天一定一定认真复习 🫡

战论文,但是感觉看的很慢而且很难抓住要点
很想了解其他人是怎么快速看完论文,抓住要点并且学习的。一般一篇论文アイラちゃん总会花上 3-5 天(全力)才能看完......

下午看的论文是 sigcomm'14 很经典的 CONGA,一篇针对数据中心的分布式拥塞感知与负载均衡方案。(只看完了动机和目的。。。 🐷)

部分的要点

CONGA 观察到了 ECMP 在负载均衡方面的缺陷:

  • 爆发大流时受限于哈希随机分配,碰撞概率增大导致负载不均衡。
  • 仅关注局部信息而未关注到潜在下游通路的拥塞影响。
    导致了链路故障情况下即使有冗余也使得成功送达流量下降 40%。

并且,针对其他解决方案的不足:如中心化调度导致的数据中心场景下流量快速变化的反应不足,局部路由特性对全局掌握不佳,基于终端主机的传输层协议增加传输层复杂度并且无法控制绕开内核具有自身协议栈的高性能应用,提出了属于自己的方案:

  • 分布式框架,允许在 RTT 尺度下进行拥塞反应。
  • 全局拥塞信息控制,leaf-leaf 控制快速传输网络拥塞指标
  • 独立于传输层的网络层部署,避免影响终端主机和引入复杂的传输层控制。

需要满足:高效性,传输层独立,不对称性稳定,可增量部署,可以针对 Leaf-spine 拓扑优化。

img

晚上要复习数学了~论文明天再继续看,CONGA 是怎么设计的。

图来自 X: @ sei_umehara

image|690x418

❤️
4
#26 · (edited)
sumire アイラちゃん

看不懂喵😭
窝是来看美图的喵 🫠

❤️
2
#27 ·

尽力做到每大更一次贴一张图 🥰

❤️
1
#28 ·
sumire アイラちゃん

好的喵 🥰

#29 ·

2025 年 6 月 1 日 星期一 天气:中雨

上午:

https://xjtu.app/t/topic/14653/23

下午:

https://xjtu.app/t/topic/14653/25

晚上:
先结束了一元积分的基础复习。先把知识点和基础题都过一遍就好。
数学复习到了多元函数微分,最为头疼的还是多元函数连续/可导/可微/存在极限的关系,还是要记一下这张图 😵‍💫

截屏 2025-06-01 22.36.14|690x112

祝各位晚安,好梦~ 🥰

X: @Tenkaichiho0

image|690x482

❤️
4
#30 ·
sumire アイラちゃん

lz 好自律🥹

长恨此身非我有 何时忘却营营

❤️
2
#31 · (edited)
青年杰出贡献上交大門人 紫金港第一皮革<・)))><<

大一大二一点不自律 🥲现在只是为了抱佛脚,看看能不能继续上学 😭
其实我更想打 MC,每天 🐖,但是边缘人太折磨了,又不想太早出来工作,想读硕士后再工作

❤️
4
#32 ·
sumire アイラちゃん

话说 LZ 有 paper 的 readlist 吗,还是组里相关的任务什么的

❤️
2
#33 · (edited)
Zerick Zerick

是暑期打算在实验室实践(必修,可以走企业实践也可以在学校实验室实践),偏网络仿真方向(开发),目前是学长给了“负载均衡”的相关文献调研,所以读论文,后面还要上 ns3 开发 😇

❤️
4
#34 ·
sumire アイラちゃん
アイラちゃん,post:31, topic:14653, username:sumire:

每天 🐖

我也想做一只快乐的皮革兔🥹

长恨此身非我有 何时忘却营营

❤️
2
#35 · (edited)
青年杰出贡献上交大門人 紫金港第一皮革<・)))><<

其实有好多想做的事
想自驾游从上海回家(海南海口),想学日语考过 N2 然后出国玩一下,想要自驾游从四川到西藏,有很多想做的事,如果有机会一定会好好玩一玩 😋

高考结束后的那个暑假几乎完全没有了,后面每个暑假都被小学期所占据,没有多少时间玩,有点可惜 🥲

悟已往之不谏,知来者之可追

❤️
4
#36 ·
sumire アイラちゃん
アイラちゃん,post:25, topic:14653, username:sumire:

很想了解其他人是怎么快速看完论文,抓住要点并且学习的。

+1,我现在非常容易陷入到实现里出不来,但是不看实现又 get 不到 paper 在干什么。
感觉还是读得太少了不知道学界现状,缺少 taste(x

❤️
4
#37 · (edited)
Zerick Zerick

对的,可能是需要积累吧。现在总是有很多陌生的术语/词汇,所以阅读的时候磕磕绊绊,但是读多了积累多了应该就快一些了 :cat_mouse:

❤️
3
#39 ·
sumire アイラちゃん
アイラちゃん,post:35, topic:14653, username:sumire:

想自驾游从上海回家(海南海口),想学日语考过 N2 然后出国玩一下,想要自驾游从四川到西藏

好厉害啊🥹
希望 lz 有朝一日能实现这些目标吧

长恨此身非我有 何时忘却营营

❤️
2
#40 ·
sumire アイラちゃん

同 😭驻波感觉目前不靠任何辅助阅读的手段就会读的很慢,或者晕乎乎的💦常常是看到一半就忍不住让 GPT 翻译了 + 总结要点

❤️
5
#41 · (edited)

アイラちゃん在 zotero 里加装了 bionic 插件

https://github.com/windingwind/bionic-for-zotero

截屏 2025-06-01 23.24.01|690x226

效果是这样的,会稍微有所提升阅读速度,浏览器アイラちゃん也会在阅读长 blog 的时候启用插件辅助阅读
一般来说长文阅读アイラちゃん很容易丢失上下文信息或者不专注(包括中文),阅读很慢,这样会稍微快一些

❤️
3
#42 ·
sumire アイラちゃん

这样吗,有点意思🤔
(确实感觉怪提神的 :tieba_laugh:
驻波回去也试试喵

❤️
4
#43 · (edited)

今天的天气很舒服,所以上午偷懒了一个小时才起床 🥲

X:@Gameillust_AI

image|357x500

上午结束!说实话有些遗憾,因为刷 leetcode 解题的速度还是比较慢,需要进一步熟悉知识点 + 提升解题/写代码的速度。

每日一题是经典的贪心!
135. 分发糖果 (H)(2025.06.02)

C++
class Solution {
public:
    int candy(vector<int>& ratings) {
        // Two times iteration.
        vector<int> ans;
        int count = 1;
        ans.emplace_back(count++);
        for(int i = 1; i < ratings.size(); i++) {
            if(ratings[i] > ratings[i-1]) {
                ans.emplace_back(count++);
            }
            else {
                count = 1;
                ans.emplace_back(count++);
            }
        }
        

        #ifdef DEBUG
        cout << ans.size() << ' ' << ratings.size() << '\n';
        for(int i = 0; i < ans.size(); i++) {
            cout << ans[i] << ' ';
        }
        cout << '\n';
        #endif

        count = 1;
        for(int i = ratings.size() - 1; i > 0; i--) {
            if(ratings[i-1] > ratings[i]) {
                ans[i-1] = max(ans[i-1], ++count);
            }
            else {
                count = 1;
                ans[i-1] = max(ans[i-1], count);
            }
        }
        
        #ifdef DEBUG
        cout << ans.size() << ' ' << ratings.size() << '\n';
        for(int i = 0; i < ans.size(); i++) {
            cout << ans[i] << ' ';
        }
        cout << '\n';
        #endif

        return reduce(ans.begin(), ans.end());
    }
};
Go
func candy(ratings []int) int {
	n := int(len(ratings))
	ans := make([]int, n)
	count := 1
	ans[0] = count
	count++

	for i := 1; i < n; i++ {
		if ratings[i-1] < ratings[i] {
			ans[i] = count
			count++
		} else {
			count = 1
			ans[i] = count
			count++
		}
	}

	count = 1
	for i := n - 1; i > 0; i-- {
		if ratings[i-1] > ratings[i] {
			count++
			ans[i-1] = max(ans[i-1], count)
		} else {
			count = 1
		}
	}
	var final int = 0
	for i := 0; i < n; i++ {
		final = final + ans[i]
	}
	return final
}

继续复习图论:这是图论中经典的拓扑排序,采用 Kahn 算法。
https://oiwiki.com/graph/topo/#kahn-算法

1591. 奇怪的打印机 II (2291H)

C++

好麻烦的题目

class Solution {
    public:
        bool isPrintable(vector<vector<int>>& targetGrid) {
            // The tuple has color -> (up, down, left, right).
            unordered_map<int, tuple<int,int,int,int>> color_mat;

            // Find the tuple mat from the graph.
            for(int i = 0; i < targetGrid.size(); i++) {
                for(int j = 0; j < targetGrid[i].size(); j++) {
                    int color = targetGrid[i][j];
                    if(color_mat.find(color) == color_mat.end()) {
                        color_mat[color] = make_tuple(INT_MAX / 2, 0, INT_MAX / 2, 0);
                    }
                    const auto & [up, down, left, right] = color_mat[color];
                    color_mat[color] = make_tuple(min(up, i), max(down, i), min(left, j), max(right, j));
                }
            }

            // Search the matrix and find the topology order.
            unordered_map<int, unordered_set<int>> graph;
            unordered_map<int, int> inDegree;
            for(const auto & ele: color_mat) {
                const int & color = ele.first;
                const auto & [up, down, left, right] = ele.second;
                graph[color] = unordered_set<int>();
                if(inDegree.find(color) == inDegree.end()) {
                    inDegree[color] = 0;
                }
                for(int i = up; i <= down; i++) {
                    for(int j = left; j <= right; j++) {
                        if(targetGrid[i][j] != color && graph[color].find(targetGrid[i][j]) == graph[color].end()) {
                            graph[color].insert(targetGrid[i][j]);
                            inDegree[targetGrid[i][j]]++;
                        }
                    }
                }
            }
            
            int n = graph.size();
            queue<int> q;
            int count = 0;
            for(const auto & ele: inDegree) {
                if(ele.second == 0) {
                    q.emplace(ele.first);
                }
            }

            while(!q.empty()) {
                int cur = q.front();
                q.pop();
                count++;
                for(const auto & adj: graph[cur]) {
                    if(--inDegree[adj] == 0) {
                        q.emplace(adj);
                    }
                }
            }

            #ifdef DEBUG
            for(const auto & element: color_mat) {
                const auto & [u,d,l,r] = color_mat[element.first];
                cout << element.first << ":(" << u << ',' << d << ',' << l << ',' << r << ")\n";
            }

            for(const auto & element: graph) {
                cout << element.first << " -> (";
                for(const auto & adj: element.second) {
                    cout << adj << ',';
                }
                cout << '\n';
            }

            for(const auto & element: inDegree) {
                cout << element.first << ": " << element.second << '\n';
            }

            cout << count << ' ' << n << '\n';
            #endif

            return count == n;
        }
    };

下午要和同学做星期四上午的 pre,以及交换星期二的数据挖掘推荐系统的展示 demo。看来今天下午又无法读论文了......没有意义的大作业真的害人不浅,强烈抨击金课! 😤 先去 🐷啦~

❤️
5
#44 ·

🐖

Screenshot_20250602_173316_edu.sjtu.infoplus.taskcenter|226x500

❤️
7
#45 ·
sumire アイラちゃん

自律 🏃

❤️
3
#46 ·
dCosmos i-BuProfen

再不跑就生锈了 🥲
现在又下雨了完蛋了 😇

❤️
3
#47 ·
sumire アイラちゃん

好自律
对我来说 跑步一直是极度痛苦的事情😖

长恨此身非我有 何时忘却营营

❤️plus1
4
#48 ·
sumire アイラちゃん

既不想上学也不想上班 我也想每天 🐖
想到将来还要至少上 20 年班我就不行了😭

此人不语,只是一味地在门里生产废料。

❤️plus1
7
#49 ·
兴庆宫第一迷路幽灵 post deleted by author

我也不想当社畜 😭

❤️
2
mod
#50 ·
兴庆宫第一迷路幽灵 post deleted by author

为什么才 20 年

❤️
3
#51 ·
emu_otori 鳳 笑夢

三十五岁危机 :rolling_on_the_floor_laughing_mouse:

此人不语,只是一味地在门里生产废料。

❤️🥺️
4
#52 ·

2025 年 6 月 2 日 星期一 天气:小雨转阴

上午:
https://xjtu.app/t/topic/14653/43

下午和晚上:和同学完成星期四 ppt 的制作,以及星期二 demo 的制作。但是没想到我的 baseline 数据竟然不见了!平台的监控数据只保存 14 天,所以今晚要赶紧取得数据补充好我们的 PPT。PPT 上涉及到了模型、算法改动后与 baseline 的对比,虽然效果好像都没有比 baseline 好,甚至比 baseline 差,但还是要展示出来,分析出来效果不好的原因。但是同学训练的 reward 版本很好。

晚上一直在处理数据和 PPT,一点也不想搞了,好累口牙~~~

https://xjtu.app/t/topic/14653/44

希望能坚持自律~不然身体会垮掉的 😥

明天又要上课了,不想上课,不想工作 🥲 只想快乐地 🐷~

祝大家有美好的新的一周!晚安~

X: @ComikeMaster
image|376x500

❤️🥰️
5
#53 ·

坚持每日一题是我的 leetcode 账户名,所以就算今天上午 pre,我也要完成它!

(小声:其实做过了)

1298. 你能从盒子里获得的最大糖果数 (1825H)(2025.06.03)

C++
class Solution {
public:
    int maxCandies(vector<int>& status, vector<int>& candies, vector<vector<int>>& keys, vector<vector<int>>& containedBoxes, vector<int>& initialBoxes) {
        // 2 times bfs. First get all the boxes final status. Second get the candies.
        queue<int> q;
        for(const auto & init: initialBoxes) {
            q.emplace(init);
        }
        while(!q.empty()) {
            int cur = q.front();
            q.pop();
            if(status[cur] == 1) {
                for(const auto & key: keys[cur]) {
                    status[key] = 1;
                }
            }
            for(const auto & adj: containedBoxes[cur]) {
                q.emplace(adj);
            }
        }
        // Then get the boxes candies.
        int ans = 0;
        for(const auto & init: initialBoxes) {
            q.emplace(init);
        }
        while(!q.empty()) {
            int cur = q.front();
            q.pop();
            if(status[cur] == 1) {
                ans += candies[cur];
            }
            for(const auto & adj: containedBoxes[cur]) {
                q.emplace(adj);
            }
        }
        return ans;
    }
};

下午先战数据库作业,然后准备后天 pre 的材料 + 再看看做好的复习笔记准备后天下午的考试!
祝自己一切顺利!

X: @kasuga_iz

image|370x500

❤️
3
#54 · (edited)

感觉好像什么都在坏掉

今天感觉心脏有点难受,一个月前买的 pad 的充电线坏了,Mac 的充电线也坏了,type-C aux 转接线也坏了,跑步的鞋也开裂了,今早书包也坏了一个口子出来(看错了,书包是好的 🤣)

只能重新买了吗,但是开销挺大的 🥲

❤️
3
#55 ·
sumire アイラちゃん

那很坏了 🤣
🫳

❤️
2
#56 ·

战数据库事务处理 😤
晚上再补齐 OCC( ✅️ )和 MVCC ⭕️ 🐷

X:@haimiya_neno

image|382x500

事务处理与并发控制

事务基础与并发控制

事务

  • 事务 (Transaction) 是什么?
    • 是一组数据库运算的集合,可以抽象成一个的不可分的逻辑工作单元

ACID 特性

  • 事务具有 ACID 特性
    • Atomicity: 原子性,即不可分割。事务要么完全执行,要么完全不执行。
    • Consistency: 事务必须保持数据库系统满足持续性,也就是满足数据库系统中的原先拥有的关系和条件。
    • Isolation: 隔离性,每个事务都是独立运行,相当于仅仅在单独运行自己。
    • Durability: 持续性。事务必须可以从错误中恢复。

并发控制

  • 什么是并发控制?并发控制的目的是什么?
    • 并发控制是数据库系统保证多个事务运算正确交叠的机制。目的是为了保证事务之间的隔离性,同时增加数据库处理速度,提高吞吐率。

保证正确的交叠:从序列化执行开始

为了简化调度方式,将数据库内的所有操作都看做仅有对特定资源读取写入操作。我们用 Ri(A)R_i(A) 表示第 i 个事务读取数据 A,Wi(A)W_i(A) 表示第 i 个事务写入数据 A。

序列化调度与等价调度

  • 没有任何交叠操作的调度 -> 序列化调度。即完成一个事务的所有操作才去执行下一个事务的操作。
  • 等价调度是一组执行效果相同的调度的集合。

可以序列化的调度

  • 具有交叠操作的调度等价于某些事务的序列化操作。
  • 每个可序列化的调度都可以确保持续性的时候,我们的序列化调度是可持续的
  • 需要我们判断调度是否可序列化。

判断调度可序列化

矛盾操作

  • 一对矛盾的操作将具有:
    • 不同的事务面向同一份资源
    • 至少有一个操作是写操作
  • 这样我们有:(R1W2 不可重复读),(W1R2 脏页读),(W1W2 更新丢失) 均为矛盾操作。(目前不考虑假性读取和写入偏移)

可序列化的不同层级

  • 冲突可序列 (confilict serializability)

    • 两个调度是冲突等价的,当且仅当
      • 拥有相同事务且事物内部操作相同。
      • 两个调度中冲突操作的顺序是相同的。也就是说如果调度一中是 (R1W2),那么调度二也必须保证 R1 在 W2 之前。
    • 调度 SS 是冲突可序列的,当它
      • 冲突操作上的顺序某些序列化调度相同。也就是说,你可以将他转换成序列化调度。
  • 视图可序列 (view serializability)

    • 两个调度是视图等价的当它们
      • 事务 1 在调度 1 中读取的初始值和在调度 2 中读取的初始值相同。
      • 事务 1 在调度 1 中读取到事务 i 写入的值,则在调度 2 中也应该读取到事务 i 写入的值。
      • 所有的最终结果都必须由一个事务来完成。
  • 很显然冲突可序列化是比视图可序列化更严格 的。

前序图

  • 判断是否冲突可序列化的简单的方法。
  • 每个事务作为一个节点。每个冲突操作对作为一条边。
  • 当前序图是有向无环图时,恭喜你它是冲突可序列化的。

并发控制方法

为了保证得到正确的交叠操作调度,我们需要一些并发控制方法。

锁的类型(其实是读写锁换皮)

  • 共享锁:用于读操作的共享锁。
  • 排它锁:用于写操作的排它锁。
可执行判断 共享锁 排它锁
共享锁 ✅️ ❌️
排它锁 ❌️ ❌️

简单的排它锁和共享锁无法保证可序列性。

二阶段锁

  • 阶段一:获得锁

    • 每个事务获取他所需要的锁。
    • 可能被拒绝或允许,但是在该阶段不允许有释放锁的行为
  • 阶段二:释放锁

    • 每个事务释放它所需要的锁。
    • 不允许任何事务获得锁
    • 严格的二阶段锁:在所有事务结束后才能统一释放锁。可以解决脏页读问题。
    • 二阶段锁可能导致死锁。通过检测和预防来避免死锁 (银行家算法等...)
    • 这里不探索如何解决死锁。
  • 一个调度是严格的当一个事务写入一份数据后,其他事务不能读取或覆盖这份数据,直到该事务终结。

  • 可以看出严格程度:严格序列化 > 严格二阶段锁 > 冲突可序列化 > 视图可序列化

时间戳排序控制 (T/O)

  • 采用时间戳来决定序列化调度中事务执行的顺序。当 TS(T1)<TS(T2) 的时候,执行顺序必须为 T1 -> T2.
  • 基础时间戳
    • 事务自身将拥有时间戳;TS( TiT_i )
    • 每个数据对象也将有自己的时间戳。
      • 数据 X 的读时间戳:R(X)
      • 数据 X 的写时间戳:W(X)
基础时间戳控制
  • 读操作

    • 当 TS(T) < W(X) 的时候,回滚并重新开始,赋予新的 TS(T).
    • 否则持续执行并且 R(X)=max(R(X),TS(T))R(X)=\max(R(X),TS(T)).
    • 允许拷贝一份 X 来保证重复读取。
  • 写操作

    • 当 TS(T) < W(X) 或者 TS(T) < R(X) 的时候,回滚并重新开始,赋予新的 TS(T).
    • 否则持续执行并且 W(X)=max(W(X),TS(T))W(X)=\max(W(X),TS(T))
  • 基础的时间戳操作保证了冲突可序列性质。

托马斯写 + 时间戳控制
  • 写操作处有所不同。

    • 当 TS(T) < R(X) 的时候,回滚。
    • 当 TS(T) < W(X) 的时候,忽略写操作,继续执行(因为很快时间戳后面的事务的写操作将覆盖本次的写操作)。
    • 否则持续执行并且 W(X)=max(W(X),TS(T))W(X)=\max(W(X),TS(T))
  • 很明显仅保证视图可序列性。

OCC(乐观并发控制)

  • 时间戳协议。
  • DBMS 为每一个事务创建了一个私有的工作空间
    • 每个被读取的对象将被复制到工作空间中,对对象的编辑也将加入到工作空间中。
    • 当事务提交时,DBMS 将会对比工作空间写集合,每个事务的写空间相同时,装载到全局数据库中。
三阶段
  • Read,读取。跟踪每个事务的读、写集合,储存他们的写入对象到私有的工作空间中。DBMS 将会复制一个事务中所有需要的元组到共享数据库中保证可重复读。
  • Validation,验证。给每一个事务独有的时间戳,检查他们是否于其他对象相互冲突。
    • 当事务唤起提交时,进入验证部分。
    • 前向验证:检查正在提交中的事务读/写集合是否与活动中的未提交事务相互重叠。
      • 检查时间戳。当提交事务时间戳小于其他活动事务时,需要满足三个条件:
        • (1) 其他事务读阶段位于当前事务写阶段完成之后。R2(A)>W1(A)
        • (2) 其他事务写阶段在当前事务写阶段完成之后。W2(A)>W1(A), 并且 当前事务没有修改任何其他活动事务要读取的对象。
        • (3) 其他事务读阶段在当前事务读阶段完成之后。R2(A)>R1(A), 并且当前事务不修改任何T2 将会读取或写入的对象。
      • 反向验证:检查正在提交中的事务读/写集合是否与活动中的已提交事务相互重叠。仍然遵循三条原则。
  • Write,写。当验证成功时,对所有已经编辑过的对象设置写时间戳,装载他们进入全局数据空间。否则回滚,中断事务。
❤️
4
#57 ·

2025 年 6 月 3 日 星期二 天气:多云

上午:
Demo,以及

https://xjtu.app/t/topic/14653/53

下午和晚上:

https://xjtu.app/t/topic/14653/56

不过没太看明白 MVCC,明天补上来 Note,再 copy 到 blog 上~
星期五又要组会,要炸了,アイラちゃん还没看完 reading list,明天一整天要加油看完 🥲

祝大家好梦~晚安 nya
X:@OuToTmeM
image|355x500

❤️
2
#58 · (edited)

忙晕了,提前更一下日记楼~

2025 年 6 月 4 日 星期三 天气:多云

上午修改明天准备汇报的 ppt,评测结果出来了,强化学习对抗实在是太折磨人了,Level3 的胜率才 25%,不过 Level2 和 Level1 我们的胜率都是 100%。还是可以的吧。
其实做了很多的尝试,更换模型和算法,但是很显然这是不正确的。对抗性最重要的就是 reward 设计,前面的部分应该是在 reward 设计完了后再进行的工作。战略上的失误使得我们还是失去了一些优势。果然盲目的勤奋是没有办法掩盖战略上的懒惰的。这一点需要深思。

下午抽时间 leetcode 保持手感。

3403. 从盒子中找出字典序最大的字符串 I

C++
class Solution {
public:
    string lastSubstring(string s) {
        int i = 0, j = 1, n = s.size();
        while (j < n) {
            int k = 0;
            while (j + k < n && s[i + k] == s[j + k]) {
                k++;
            }
            if (j + k < n && s[i + k] < s[j + k]) {
                int t = i;
                i = j;
                j = max(j + 1, t + k + 1);
            } else {
                j = j + k + 1;
            }
        }
        return s.substr(i, n - i);
    }
    string answerString(string word, int numFriends) {
        if(numFriends == 1) {
            return word;
        }
        string last = lastSubstring(word);
        int n = word.size(), m = last.size();
        return last.substr(0, min(m, n - numFriends + 1));
    }
};

LCR 114. 火星词典(非常不推荐做,纯纯一废题)

C++
#define DEBUG
#undef DEBUG
class Solution {
public:
    string alienOrder(vector<string>& words) {
        unordered_map<char, unordered_set<char>> graph;
        unordered_map<char, int> inDegree;
        bool flag = false;
        auto add_edge = [&](const string & l, const string & r) -> void {
            int i = 0;
            for(i = 0; i < min(l.length(), r.length()); i++) {
                if(graph.find(l[i]) == graph.end()) {
                    graph[l[i]] = unordered_set<char>();
                }
                if(inDegree.find(l[i]) == inDegree.end()) {
                    inDegree[l[i]] = 0;
                }
                if(l[i] != r[i] && graph[l[i]].find(r[i]) == graph[l[i]].end()) {
                    flag = true;
                    graph[l[i]].insert(r[i]);
                    inDegree[r[i]]++;
                    break;
                }
                else if(l[i] != r[i]) {
                    flag = true;
                    break;
                }
            }
            if(!flag && l.length() > r.length()) {
                return;
            }
            flag = true;
            int temp = i;
            for(; i < l.length(); i++) {
                if(graph.find(l[i]) == graph.end()) {
                    graph[l[i]] = unordered_set<char>();
                }
                if(inDegree.find(l[i]) == inDegree.end()) {
                    inDegree[l[i]] = 0;
                }
            }
            i = temp;
            for(; i < r.length(); i++) {
                if(graph.find(r[i]) == graph.end()) {
                    graph[r[i]] = unordered_set<char>();
                }
                if(inDegree.find(r[i]) == inDegree.end()) {
                    inDegree[r[i]] = 0;
                }
            }
        };

        // Step 1: Add edges.
        if(words.size() == 1) {
            flag = true;
            for(int i = 0; i < words[0].length(); i++) {
                if(graph.find(words[0][i]) == graph.end()) {
                    graph[words[0][i]] = unordered_set<char>();
                }
                if(inDegree.find(words[0][i]) == inDegree.end()) {
                    inDegree[words[0][i]] = 0;
                }
            }
        }
        else {
            for(int i = 0; i < words.size(); i++) {
                for(int j = i + 1; j < words.size(); j++) {
                    add_edge(words[i], words[j]);
                }
            }
        }

        #ifdef DEBUG
        for(auto & elem: graph) {
            cout << elem.first << ": ";
            for(const auto & adj: elem.second) {
                cout << adj << ' ';
            }
            cout << '\n';
        }
        for(auto & elem: inDegree) {
            cout << elem.first << ": " << elem.second << "\n";
        }
        string flag_str = (flag == true) ? "true" : "false";
        cout << flag_str << '\n';
        #endif

        // Step 2: TopoSort.
        queue<char> q;
        string ans;
        for(const auto & ch: inDegree) {
            if(ch.second == 0) {
                q.emplace(ch.first);
            }
        }
        while(!q.empty()) {
            char ch = q.front();
            ans.push_back(ch);
            q.pop();
            for(const auto & adj: graph[ch]) {
                if(--inDegree[adj] == 0) {
                    q.emplace(adj);
                }
            }
        }
        return ans.length() == graph.size() && flag ? ans : "";
    }
};

2127. 参加会议的最多员工数

C++

基于基环树的思想。

class Solution {
public:
    int maximumInvitations(vector<int>& favorite) {
        int n = favorite.size();
        vector<vector<int>> reverse_graph(n);
        queue<int> q;
        vector<int> inDegree(n, 0);

        for(int i = 0; i < n; i++) {
            inDegree[favorite[i]]++;
        }
        for(int i = 0; i < n; i++) {
            if(inDegree[i] == 0) {
                q.emplace(i);
            }
        }

        while(!q.empty()) {
            int cur = q.front();
            q.pop();
            // Build reverse_graph;
            reverse_graph[favorite[cur]].emplace_back(cur);
            if(--inDegree[favorite[cur]] == 0) {
                q.emplace(favorite[cur]);
            }
        }
        
        // Dfs reverse graph find the shortest edge.
        auto dfs = [&](this auto && dfs, int from) -> int {
            int max_depth = 1;
            for(const auto & adj: reverse_graph[from]) {
                max_depth = max(max_depth, dfs(adj) + 1);
            }
            return max_depth;
        };

        // Find the cycle.
        int ring = 0, chain = 0;
        for(int i = 0; i < n; i++) {
            if(inDegree[i] == 0) {
                continue;
            }
            inDegree[i] = 0;
            int tmp_ring = 1;
            for(int adj = favorite[i]; adj != i; adj = favorite[adj]) {
                inDegree[adj] = 0;     // mark as visited.
                tmp_ring++;
            }
            
            if(tmp_ring == 2) {
                chain = chain + dfs(i) + dfs(favorite[i]);
            } else {
                ring = max(ring, tmp_ring);
            }
        }
        return max(chain, ring);
    }
};

然后焦虑/抑郁状态出现了,突然一下子什么都不想干,只能停下手中的学习任务去外面走一走 🥲
拍照的地方在兰香湖附近,是アイラちゃん心情不好的时候最常去的地方。只要在安静的地方发上半个小时的呆,好像什么都会变好的。有时候止不住地想,是不是我选择了错误的道路,选择了错误的人生,还是什么时候做了错误的事情呢,以至于现在进退两难,也不知道未来在哪里,为了尝试保研也没有认真的去找工作。如果,如果考研和保研都失败了,没有实习经验的アイラちゃん又应该怎样才能找到理想的工作呢,如果不找本专业的工作我又会什么呢。现在的アイラちゃん还不知道答案是什么,未来在何处。

2391749040045_.pic|666x500
2401749040047_.pic|666x500
2411749040048_.pic|666x500

今天晚上就是准备明天下午的考试了,希望能够一切顺利吧,明天上午的 pre,明天下午的考试。星期五的组会明天考完试再准备吧。
祝大家今晚好梦~

X: @ji10me
image|415x500

❤️
4
#59 ·
sumire アイラちゃん
アイラちゃん,post:58, topic:14653, username:sumire:

现在的アイラちゃん还不知道答案是什么,未来在何处。

我也是😭

此人不语,只是一味地在门里生产废料。

❤️
3
admin
#60 ·
sumire アイラちゃん
アイラちゃん,post:58, topic:14653, username:sumire:

如果,如果考研和保研都失败了,没有实习经验的アイラちゃん又应该怎样才能找到理想的工作呢,如果不找本专业的工作我又会什么呢。

答案是并不会怎么样 😁 你想太多了

❤️🤠️🥺️🥹️
9