刚看到个贴子,说阿里一个P7加V员工晒工资,177w总包,笑得合不拢嘴 🤯。下面不少人直呼羡慕,也有人提醒别轻易晒工资。
我觉得这事吧,工资高当然让人眼红,但一晒出来,风险和麻烦也跟着来了。有人羡慕,有人嫉妒,甚至可能引来误解和不必要的矛盾。职场上最忌讳的就是让别人拿着你的数字和自己比,比较到最后,容易让团队关系变味。
说到底,工资是价值的体现 ,不是炫耀的资本。低调做人,高调做事,才是最稳妥的职场生存法则。毕竟真正的安全感,从来不是别人羡慕的眼光,而是你自己手里牢牢握住的筹码。【备注:文末可领最新资料】
算法题:查找具有螺旋学习模式的学生
昨天晚上十一点多,在公司楼下吹风,咱组小李丢给我一堆学习日志,说:“东哥,你看看谁是那种…螺旋学的学生?就是学一圈又回来复盘,越转越高那个。”我当时困得要死,但一听这关键词,脑子就醒了:这不是要从时间序列里捞“周期性回访 + 逐步提升”的人嘛。
别搞太学术,落地三条就行: 1)同一学生在同一知识点上多次回访(≥3次)。 2)每次回访的得分/掌握度整体向上(允许小抖动)。 3)回访的间隔大体变长(像套螺旋往外扩,间隔比例大于某阈值,比如1.2,给个容忍度)。
满足两条半以上(前两条必须),我就认为这人对该知识点呈螺旋学习;若一个学生在多个知识点都这样,那基本稳了。
把日志按(学生→知识点)分组,时间排序。对每条序列,计算:
-
提升率:后一次得分 − 前一次得分,允许偶发下降但整体线性回归斜率>0; -
间隔比:gap[i+1]/gap[i] 的中位数是否 > ratioMin(比如1.2),再给±epsilon(0.15)容忍; -
轮数:有效回环次数≥3。最后按知识点打标签,再汇总到学生级别。
import java.util.*;
import java.util.stream.*;
class StudyRecord {
String studentId, topicId;
long ts; // 时间戳
double score; // 得分或掌握度[0,100]
public StudyRecord(String s, String t, long ts, double sc){this.studentId=s;this.topicId=t;this.ts=ts;this.score=sc;}
}
class SpiralDetector {
staticclass TopicJudge {
boolean isSpiral; double slope; double gapRatioMedian;
}
// 主入口:返回具有螺旋学习模式的学生ID
public static Set<String> findSpiralStudents(List<StudyRecord> logs,
int minRounds,
double minSlope,
double ratioMin,
double ratioTolerance,
int minSpiralTopics) {
// 学生 -> 话题 -> 时间排序序列
Map<String, Map<String, List<StudyRecord>>> grouped =
logs.stream().collect(Collectors.groupingBy(r -> r.studentId,
Collectors.groupingBy(r -> r.topicId)));
Set<String> result = new HashSet<>();
for (var eStu : grouped.entrySet()) {
String stu = eStu.getKey();
int spiralTopics = 0;
for (var eTopic : eStu.getValue().entrySet()) {
List<StudyRecord> seq = new ArrayList<>(eTopic.getValue());
seq.sort(Comparator.comparingLong(r -> r.ts));
TopicJudge judge = judgeTopic(seq, minRounds, minSlope, ratioMin, ratioTolerance);
if (judge.isSpiral) spiralTopics++;
}
if (spiralTopics >= minSpiralTopics) result.add(stu);
}
return result;
}
// 判断某学生在某话题是否呈螺旋
private static TopicJudge judgeTopic(List<StudyRecord> seq,
int minRounds,
double minSlope,
double ratioMin,
double ratioTolerance) {
TopicJudge out = new TopicJudge();
if (seq.size() < minRounds) { out.isSpiral=false; return out; }
// 1) 线性回归斜率(时间->得分)
double slope = linearSlope(seq);
out.slope = slope;
if (slope < minSlope) { out.isSpiral=false; return out; }
// 2) 间隔比是否“往外扩”
List<Long> gaps = new ArrayList<>();
for (int i=1;i<seq.size();i++) gaps.add(seq.get(i).ts - seq.get(i-1).ts);
if (gaps.stream().anyMatch(g->g<=0)) { out.isSpiral=false; return out; }
List<Double> ratios = new ArrayList<>();
for (int i=1;i<gaps.size();i++) ratios.add(gaps.get(i)*1.0 / gaps.get(i-1));
double median = median(ratios);
out.gapRatioMedian = median;
// 给容忍:允许少量≤ratioMin,但中位数需大于 ratioMin - ratioTolerance
out.isSpiral = median >= (ratioMin - ratioTolerance) && seq.size() >= minRounds;
return out;
}
private static double linearSlope(List<StudyRecord> seq){
int n = seq.size();
double xMean = seq.stream().mapToDouble(r->(double)r.ts).average().orElse(0);
double yMean = seq.stream().mapToDouble(r->r.score).average().orElse(0);
double num=0, den=0;
for (StudyRecord r: seq){
double dx = r.ts - xMean;
num += dx * (r.score - yMean);
den += dx * dx;
}
return den==0?0:num/den;
}
private static double median(List<Double> vs){
if (vs.isEmpty()) return1.0;
vs.sort(Double::compareTo);
int m = vs.size()/2;
return vs.size()%2==1?vs.get(m):(vs.get(m-1)+vs.get(m))/2.0;
}
}
publicclass Main {
public static void main(String[] args) {
// 随便造两条…算了不造多了
List<StudyRecord> logs = List.of(
new StudyRecord("u1","math", 1_000_000L,60),
new StudyRecord("u1","math", 1_100_000L,70),
new StudyRecord("u1","math", 1_350_000L,78),
new StudyRecord("u1","algo", 1_000_000L,55),
new StudyRecord("u1","algo", 1_250_000L,66),
new StudyRecord("u2","math", 1_000_000L,60) // 普通
);
Set<String> spiral = SpiralDetector.findSpiralStudents(
logs, 3, 0.00001, 1.2, 0.15, 1);
System.out.println(spiral); // 预期包含 u1
}
}
复杂度基本 O(N log N)(主要在分组内排序)。坑主要两类: 1)时间戳不准、批量导入导致“同秒”记录,要先做去噪/合并。 2)得分抖动:别死卡“次次变高”,用整体斜率和中位数间隔比抗噪更稳。
行了我先去续杯咖啡,回头有人要看可视化我再补个图…
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

