优雅永不过时-每日签到功能的优雅实现
需求简介
需要在页面中上展示该用户本月的签到情况,已经签到过的日期就要做一个标记。
如下图
这里主要解决的是数据存储和读取的问题。
数据结构
简单解决方案
简单思考的话很好解决,可以建议使用下面的表结构来实现(去除非必要字段)
字段名 | 字段类型 | 说明 |
---|---|---|
user_id | int | 用户 |
month | int | 所属月份 |
day | int | 签到日 |
这样的话简单明了,但是有一个问题,一个用户一个月就是30条数据,50万月度活跃用户(设计目标)一年就能产生 500000*30*12=180,000,000 ,也就是1.8亿条数据……
哈哈,看上去能行,实际上,呃……
进阶解决方案
上面每一次签到都记录一次数据,看上去精细(可以保存每一次操作的创建时间之类的),但是实际保存了签到的日就行了,这个设计肯定会有非常多的冗余数据的。
首先一个月最多31天,可以理解为这里只要一个长度为31的boolean的数组,序号代表日期,boolean值代表是否已经签到。
其次,boolean类型的本质不就是 01嘛!
ok了,问题解决了!
那就是一个长度为31的byte数组了!
31位的byte数组,那还不如32呢,为啥?32位直接可以转换成一个int值啊!
妙!
说干就干,数据结构可以简单变一下就行了
字段名 | 字段类型 | 说明 |
---|---|---|
user_id | int | 用户 |
month | int | 所属月份 |
day | int | 签到日集合 |
只要每次展示的时候解析day这个代表当月签到日集合的Int数值,就可以知道当月的已签到日,当月总计签到日。
按照50万月度活跃用户预估,一年能产生 500000*1*12=6000,000 ,比之前肯定是减小一个数量级了。
稳,优雅永不过时!
关键代码实现
public class DateUtils {/*** 指定日期签到** @param sign 已签到的集合* @param day 需要添加的签到日期 1,2,3...* @return*/public static Integer sign(Integer sign, Integer day) {return sign | 1 << day;}/*** 检查指定日期是否已签到** @param sign* @param day* @return*/public static boolean checkSign(Integer sign, Integer day) {return 0 != (sign & 1 << day);}/*** 统计本月已签到次数** @param sign* @return*/public static Integer countSign(Integer sign) {int count = 0;while (sign != 0) {count += (sign & 1);sign = sign >>> 1;}return count;}/*** 获取以前到的日期列表** @param sign* @return*/public static List<String> getSignDays(int sign) {List<String> result = new ArrayList<String>();int day = 0;while (sign != 0) {day++;sign = sign >>> 1;if (1 == (sign & 1)) {result.add(String.valueOf(day));}}return result;}public static void main(String[] args) {Integer defaultSign = 0;Integer sign = sign(defaultSign, 2);sign = sign(defaultSign, 2);Assert.isTrue(countSign(sign) == 1);Assert.isTrue(checkSign(sign, 2));sign = sign(sign, 13);Assert.isTrue(!checkSign(sign, 12));Assert.isTrue(checkSign(sign, 2));Assert.isTrue(checkSign(sign, 13));Assert.isTrue(!checkSign(sign, 12));Assert.isTrue(countSign(sign) == 2);for (int i = 0; i <= 31; i++) {sign = sign(sign, i);}System.out.println(getSignDays(sign).toString());}}
优雅永不过时-每日签到功能的优雅实现相关推荐
- 每日签到功能怎么实现的?
关于网友提出的" 每日签到功能怎么实现的?"问题疑问,本网通过在网上对" 每日签到功能怎么实现的?"有关的相关答案进行了整理,供用户进行参考,详细问题解答如下: ...
- js php 实现日历签到_js实现每日签到功能
本文实例为大家分享了js实现每日签到功能的具体代码,供大家参考,具体内容如下 js: var calUtil = { getDaysInmonth : function(iMonth, iYear){ ...
- 基于jQuery的日历+每日签到功能
公司要开发一个h5页面,里边有一个每日签到抽奖的功能,本以为这样的插件应该会有很多,结果找到的全都是仅生成日历的插件,于是乎就出现了下面这个东西.(前端菜鸟,请大神嘴下留情,也请小伙伴们多提宝贵意见) ...
- 每日积分返还的php代码,php实现每日签到功能
每日签到的功能,供大家参考,具体内容如下 首次签到获得1个积分,第二次签到获得2个积分,第三次签到获得3个积分,以此类推但是签到必须每天连续积分才可以递增,如果有中断再次签到时获得积分仍然从1开始递增 ...
- html+css+JavaScript实现每日签到功能
用户每日签到主要在于实现点击-签到-显示即时时间 本次使用的是原生js实现签到功能,绑定签到按钮点击需要显示的内容,获取网络时间,获取年月日,再对文字进行拼接,最后再进行插入html中的展示内容 下面 ...
- js实现每日签到功能
注:此功能是在借鉴一位前辈的功能上实现的,稍有改动,具体在哪里我又忘了,因为我都是写好了才来博客记录的,所以之前在哪里找的资料没给记住,对不住啦! 不废话,先看效果! 核心js: var calUti ...
- 公众号签到领积分怎么做?每日签到功能上架
每日签到为公众号实现了每日积分签到的的功能,对于吸粉和留存起到了非常重要的意义. 微Sir图文助手可以实现递增签到和签到上限和自定义签到签到回复的功能. 费用:接入微Sir图文助手基础服务后免费使用 ...
- java实现用户每日签到功能
java用户每日签到 签到规则 签到周期以周为单位(最大连续签到天数为 7 天),周一为新的签到周期,所有连续签到天数重新开始计算. 表字段 以下为数据库所需的字段: 代码实现 非全部的代码: /** ...
- tp5实现每日签到功能
tp5每日签到设计 数据库设计 代码实现 数据库设计 要求: 每个用户可以签到7天,连续签到7天或者中途断签都重新开始计算签到天数,签到会获取对应奖励 分析: 1.连续签到 2.签到7天或者断签重新开 ...
最新文章
- C# App.config 自定义 配置节
- JS 正则表达式(数字、正则)
- [转载]答《漫话ID》中的疑问:UniqueID和ClientID的来源
- 用Tomcat构建一个简单图片服务器
- 百度seo排名规则_百度关键词seo优化排名如何上首页
- rust异步之async、await、future
- linux清理缓存_[ERROR] Linux 的 No space left on device(磁盘空间不足)
- 「镁客·请讲」MyToken郭楠:从币情开始,做区块链链上的去中心化生态
- vuejs对象更新渲染_vue 对对象的属性进行修改时,不能渲染页面 vue.$set()
- Chrome的版本历史
- Gradle化的Android Gallery3D App
- 如何在InfoPath2010中转换主数据源
- 黑马python5.0课件_2020整理的黑马python 5.0新课程体系零基础到就业大实战
- 危险漫步_2006年糖尿病漫步-漫步之日
- Android开发项目实战:实现折叠式布局,android组件化开发与sdk
- 2010页游报告:开测222款31款停运
- 数据库,SQL语句的介绍
- 广告拦截应用将从Google应用商城中移除
- gdb设置与清除断点
- linux usb接口的音频设备
热门文章
- Java修炼之道--Web
- 交易所平台币综合研究报告 | TokenInsight
- 绝地求生服务器维护9月19日,绝地求生9.19日无法登录游戏解决方法 绝地求生9月19日登录不了?...
- 饥荒机器人怎么解锁_饥荒机器人吃不了齿轮怎么办_饥荒机器人解决方法介绍_玩游戏网...
- PowerPC栈帧理解
- 2018 考研 408 经验贴——政治和英语
- python 支付宝证书 计算SN 序列号
- 与ChatGPT玩文字冒险游戏[寻五宝石]
- Python---qq群聊天记录词云分析
- install ubuntu 5.10