文章目录

  • 一 代码实现
    • 0 开发主线
    • 1 实体类
      • (1)TagInfo
      • (2)TaskInfo
      • (3)TaskTagRule
    • 2 工具类
      • (1)连接sql的工具类
        • 测试
      • (2)专门读取properties文件的工具类
        • 测试
      • (3)对象值拷贝的工具类
    • 3 配置文件
      • (1)config.properties
    • 4 DAO层
      • (1)TagInfoDAO
      • (2)TaskInfoDAO
      • (3)TaskTagRuleDAO
      • (4)测试

一 代码实现

第一步获得标签定义、标签任务的SQL、字标签的匹配规则,存储在MySQL中,代码实现。

task-sql任务:生成标签数据,格式为userid – tag_value,如张三的id,男。每一种三级标签会把生成的数据放到一张表中。

实现步骤:

  • 1 获得标签定义、标签任务的SQL、子标签的匹配规则(这些数据存放在mysql中)

    • 1.1 如何查询MySQL:封装工具类,利用jdbc

    • 1.2 用工具类分别查询

      • 一个数:String,Int,Long
      • tag_info:一行数 hashmap javabean(UserInfo…)
      • task_info:一行数 hashmap javabean(UserInfo…)
      • task_tag_rule:一堆数,可能有很多子标签的匹配 List[UserInfo] …
    • 1.3 如何知道要执行的哪个任务:通过spark-submit将外部参数传给spark作业,使用args获得要执行的task_id和task_date

      • 如何将两个参数传入到args

        spark-submit  -driver-memory 1g
        --xx
        --xx
        --xx
        xxxx.jar   taskId  taskDate
        

        xxxx.jar 后面的值会传入到args中

  • 2 如果没有表,需要根据标签定义规则建立标签表

  • 3 根据标签定义和规则查询数据仓库

  • 4 把数据写入到对应的标签表中

0 开发主线

代码存放位置:task – sql – src –main – scala – com.hzy.userprofile.app – TaskSQLApp

package com.hzy.userprofile.appimport com.hzy.userprofile.bean.{TagInfo, TaskInfo, TaskTagRule}
import com.hzy.userprofile.dao.{TagInfoDAO, TaskInfoDAO, TaskTagRuleDAO}
import com.hzy.userprofile.util.MySqlUtilobject TaskSQLApp {def main(args: Array[String]): Unit = {//1 获得标签定义、标签任务的SQL、字标签的匹配规则,存储在MySQL中//  封装工具类,查询MySQL,jdbc//  用工具类分别查询tag_info、task_info、task_tag_rule//    一个数 string int long   一行数 hashmap javabean(UserInfo...) 一堆数List[UserInfo] ...//    可以通过args获得要执行的task_id和task_dateval taskId: String = args(0)val tastDate: String = args(1)//根据taskId查询tag_info、task_info、task_tag_rule//要定义javabean,转向task-common工程新建TagInfo,TaskInfo,TaskTagRule,对应标题1中的(1)(2)(3)//var tagInfo:TagInfo = null//val taskInfo:TaskInfo = null//val taskTagRuleList:List[TaskTagRule] = null//想查询出以上三条数据,需要定义连接MySQL的工具类,转向task-common工程,对应标题2中的(1)(2)(3)和3中的(1)
//    val maybeTagInfo: Option[TagInfo] = MySqlUtil.queryOne(// 查询一个TagInfo,有TaskId,需要查询tag_info中的tag_task_id列
//      s"""
//         | select id,tag_code,tag_name,
//         | parent_tag_id,tag_type,tag_value_type,
//         | tag_value_limit,tag_task_id,tag_comment,
//         | create_time
//         | from tag_info
//         | where tag_task_id='$taskId'
//         |""".stripMargin,
//      classOf[TagInfo],true)
//
//    if(maybeTagInfo != None){//      tagInfo = maybeInfo.get
//    }// 将以上查询sql抽取为一个方法,放在task-common中的dao层中,对应标题4中的(1)(2)(3)// 可以通过一条语句实现查询val tagInfo: TagInfo = TagInfoDAO.getTagInfoByTaskId(taskId)val taskInfo: TaskInfo = TaskInfoDAO.getTaskInfo(taskId)val taskTagRuleList: List[TaskTagRule] = TaskTagRuleDAO.getTaskTagRuleListByTaskId(taskId)println(tagInfo)println(taskInfo)println(taskTagRuleList)//2 如果没有表,需要根据标签定义规则建立标签表//3 根据标签定义和规则查询数据仓库//4 把数据写入到对应的标签表中}
}

1 实体类

(1)TagInfo

在task-common中增加实体类TagInfo,是一个样例类,样例类本身不含有无参构造函数,但是后续过程中,需要其无参构造函数,所以需要自己定义一个无参构造函数,将有参的参数都置为null则相当于无参,def this() ={ this(null,null,null,null,null,null,null,null,null,null,null,null,null ) }

定义了一个java的long,import java.lang.Long,因为scala中的long不接受null值

package com.hzy.userprofile.beanimport java.util.Date
import java.lang.Longcase class TagInfo(var id:Long,var tagCode:String,var tagName:String,var tagLevel:Long,var parentTagId:Long,var tagType:String,var tagValueType:String,var  tagValueLimit:Long,var  tagValueStep:Long,var  tagTaskId:Long,var  tagComment:String,var  createTime:Date,var  updateTime:Date) {def this()  ={this(null,null,null,null,null,null,null,null,null,null,null,null,null )}
}

(2)TaskInfo

package com.hzy.userprofile.beanimport java.util.Date
import java.lang.Longcase class TaskInfo  (var id: Long = null ,var taskName:String=null,var taskStatus:String=null,var taskComment:String=null,var taskTime:String=null,var taskType:String=null,var execType:String=null,var mainClass:String=null,var fileId:Long= null,var taskArgs:String=null,var taskSql:String=null,var taskExecLevel:Long =null,var createTime:Date=null)  {//补充无参构造函数def this()  ={this(0L,null,null,null,null,null,null,null,-1L,null,null,null,null)}
}

(3)TaskTagRule

package com.hzy.userprofile.beanimport java.lang.Longcase class TaskTagRule(var id:Long,var tagId:Long,var  taskId:Long,var  queryValue:String,var  subTagId:Long,var   subTagValue:String) {def this()  ={this(null,null,null,null,null,null  )}
}

2 工具类

(1)连接sql的工具类

MySqlUtil工具类中包含三个方法:

  • ueryList(sql: String): java.util.List[JSONObject]:返回List[JSONObject],JSON本质上也是一个HashMap,是一个KV对象,只不过能够更加容易的转换为JSON,通用结构
  • queryList[T<:AnyRef](sql: String, clazz: Class[T], underScoreToCamel: Boolean):List[T]:将数据转换成专用结构,需要传入的参数:
    • 一个sql、一个类clazz:意思为将这个sql封装成clazz的类型
    • underScoreToCamel:作用为将sql字段转换为java的驼峰结构AaBb
  • queryOne[T<:AnyRef](sql: String, clazz: Class[T] ,underScoreToCamel: Boolean): Option[T ]:查询单条数据,实现方式也是查询集合,只不过如果集合不为空,将集合中的第一条数据抓取出来
package com.hzy.userprofile.utilimport java.lang.reflect.Field
import java.sql.{Connection, DriverManager, PreparedStatement, ResultSet, ResultSetMetaData, Statement}
import java.util.Properties
import com.alibaba.fastjson.JSONObject
import com.google.common.base.CaseFormat
import scala.collection.mutable.ListBufferobject MySqlUtil {def main(args: Array[String]): Unit = {val list: java.util.List[JSONObject] = queryList("select * from base_province")println(list)}private val properties: Properties = MyPropertiesUtil.load("config.properties")val MYSQL_URL = properties.getProperty("mysql.url")val MYSQL_USERNAME = properties.getProperty("mysql.username")val MYSQL_PASSWORD = properties.getProperty("mysql.password")def queryList(sql: String): java.util.List[JSONObject] = {Class.forName("com.mysql.jdbc.Driver")//创建结果列表val resultList: java.util.List[JSONObject] = new java.util.ArrayList[JSONObject]()//创建连接val conn: Connection = DriverManager.getConnection(MYSQL_URL, MYSQL_USERNAME, MYSQL_PASSWORD)//创建会话val stat: Statement = conn.createStatementprintln(sql)//提交sql 返回结果val rs: ResultSet = stat.executeQuery(sql)//为了获得列名 要取得元数据val md: ResultSetMetaData = rs.getMetaDatawhile (rs.next) {val rowData = new JSONObject();for (i <- 1 to md.getColumnCount) {// 根据下标得到对应元数据中的字段名,以及结果中值rowData.put(md.getColumnName(i), rs.getObject(i))}resultList.add(rowData)}stat.close()conn.close()resultList}def queryList[T<:AnyRef](sql: String, clazz: Class[T], underScoreToCamel: Boolean):List[T]={Class.forName("com.mysql.jdbc.Driver");val resultList: ListBuffer[T] = new ListBuffer[T]();val connection: Connection = DriverManager.getConnection(MYSQL_URL, MYSQL_USERNAME, MYSQL_PASSWORD)val stat: Statement = connection.createStatement();val rs: ResultSet = stat.executeQuery(sql);val md: ResultSetMetaData = rs.getMetaData();while (rs.next()) {val obj: T = clazz.newInstance()for (i <- 1 to md.getColumnCount) {var propertyName: String = md.getColumnLabel(i)if (underScoreToCamel) {propertyName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, md.getColumnLabel(i))}MyBeanUtils.setV(obj,propertyName,rs.getObject(i))}resultList.append(obj);}stat.close()connection.close()resultList.toList}def queryOne[T<:AnyRef](sql: String, clazz: Class[T] ,underScoreToCamel: Boolean): Option[T ] ={println(sql)Class.forName("com.mysql.jdbc.Driver");val resultList: ListBuffer[T] = new ListBuffer[T]();val connection: Connection =DriverManager.getConnection(MYSQL_URL, MYSQL_USERNAME, MYSQL_PASSWORD)val stat: Statement = connection.createStatement();val rs: ResultSet = stat.executeQuery(sql);val md: ResultSetMetaData = rs.getMetaData();while (rs.next()) {val obj: T = clazz.newInstance()for (i <- 1 to md.getColumnCount) {var propertyName: String = md.getColumnName(i)if (underScoreToCamel) {propertyName =CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, md.getColumnName(i))}MyBeanUtils.setV(obj,propertyName,rs.getObject(i))}resultList.append(obj);}stat.close()connection.close()if(resultList!=null){Some(resultList(0))}else{None}}def insertOne[T](sql: String, obj:T ): Unit ={Class.forName("com.mysql.jdbc.Driver");val resultList: ListBuffer[T] = new ListBuffer[T]();val connection: Connection =DriverManager.getConnection(MYSQL_URL, MYSQL_USERNAME, MYSQL_PASSWORD)val pstat: PreparedStatement = connection.prepareStatement(sql)val fields: Array[Field] = obj.getClass.getDeclaredFieldsfor(i<- 1 to fields.size){val field:Field = fields(i-1);field.setAccessible(true)val value: AnyRef = field.get(obj)pstat.setObject(i,value)}val resInsert = pstat.execute()println("插入数据,返回值=>" + resInsert)}
}

测试

def main(args: Array[String]): Unit = {val list: java.util.List[JSONObject] = queryList("select * from tag_info")println(list)
}

运行上述代码进行测试,会发现抛出错误信息如下

Exception in thread “main” java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

查看maven工程中的依赖,发现驱动存在,进而查看父工程的配置文件pom.xml,发现mysql驱动的依赖为

        <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version><scope>provided</scope></dependency>

<scope>影响依赖在何时加入,provided为在编写代码时将依赖引入进去,编译可以通过,但是运行、打包时就不会加入此条依赖。

加入provided原因:task-sql程序最终会打成jar包,如果不写provided,所有的依赖都会打一个jar包,最终的jar包会变得十分臃肿,称为”胖包“,有一部分类不用放到jar包中,可以放到运行环境中,spark-lib下存在mysql驱动包,所以此处为provided。

现想要在idea中调试运行,解决办法如下图:


(2)专门读取properties文件的工具类

Properties底层实现就是一个hashmap,配置文件中“等于号”前的为K值,后面的为V值

package com.hzy.userprofile.utilimport java.io.InputStreamReader
import java.util.Propertiesobject MyPropertiesUtil {def main(args: Array[String]): Unit = {val properties: Properties =  MyPropertiesUtil.load("config.properties")println(properties.getProperty("kafka.broker.list"))}def load(propertieName:String): Properties ={val prop=new Properties();prop.load(new InputStreamReader(Thread.currentThread().getContextClassLoader.getResourceAsStream(propertieName) , "UTF-8"))prop}
}

测试

替换上述代码中main方法中的参数

 def main(args: Array[String]): Unit = {val properties: Properties =  MyPropertiesUtil.load("config.properties")println(properties.getProperty("mysql.url"))}

修改上述代码,可测试代码是否正确

(3)对象值拷贝的工具类

MyBeanUtils.setV(obj,propertyName,rs.getObject(i))希望将rs.getObject(i)获得的值拷贝到obj对象的propertyName属性中。

平常用对象赋值都是写一个固定的setA(A),如果对象中有很多值,想循环的赋值,上面写法就不行,因为A不确定,所以可以将A作为一个变量,循环执行。

package com.hzy.userprofile.utilimport java.lang.reflect.{Field, Modifier}
import java.text.SimpleDateFormat
import java.util.Locale
import scala.util.control.Breaks._object MyBeanUtils {/*** 对象相同属性copy** @param obj* @param toResult* @return* @throws Exception* 转换报错*/def copyProperties(obj: Object, toResult: Object): Unit = {if (obj == null) {return}try {val fields = toResult.getClass.getDeclaredFieldsfor (field <- fields) {breakable {field.setAccessible(true) //修改访问权限if (Modifier.isFinal(field.getModifiers()))breakif (isWrapType(field)) {val getMethodName = field.getName()val setMethodName = field.getName()+"_$eq"val getMethod = {try {obj.getClass().getMethod(getMethodName)} catch {case ex: Exception =>//  println(ex)break}}//从源对象获取get方法val setMethod =toResult.getClass.getMethod(setMethodName, field.getType)//从目标对象获取set方法val value = {val objValue = getMethod.invoke(obj) // get 获取的是源对象的值if (objValue != null && objValue.isInstanceOf[java.util.Date]) {// GMT时间转时间戳val format =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH)val formatValue = format.format(objValue)java.lang.Long.valueOf(format.parse(formatValue).getTime)} elseobjValue}setMethod.invoke(toResult, value)}}}} catch {case ex: Exception => throw ex}}/*** 是否是基本类型、包装类型、String类型*/def isWrapType(field: Field): Boolean = {val typeList = List[String]("java.lang.Integer", "java.lang.Double", "java.lang.Float", "java.lang.Long", "java.util.Optional", "java.lang.Short", "java.lang.Byte", "java.lang.Boolean", "java.lang.Char", "java.lang.String", "int", "double", "long", "short", "byte", "boolean", "char", "float")if (typeList.contains(field.getType().getName())) true else false}def getV(ref:AnyRef, name: String): Any = ref.getClass.getMethods.find(_.getName == name).get.invoke(ref)def setV(ref:AnyRef,name: String, value: Any): Unit = {ref.getClass.getMethods.find(_.getName == name + "_$eq").get.invoke(ref, value.asInstanceOf[AnyRef])}
}

核心为下述代码

def setV(ref:AnyRef,name: String, value: Any): Unit = {ref.getClass.getMethods.find(_.getName == name + "_$eq").get.invoke(ref, value.asInstanceOf[AnyRef])

使用java的反射机制,找到对象,只不过对象与java中不同,scala给属性赋值的方法叫做name + "_$eq",其中的$就是=,scala反编译重新做了一个编码。

找到name + "_$eq"方法,进行反射,进而赋值。

3 配置文件

task-common – resources 增加配置文件

(1)config.properties

hdfs-store.path=hdfs://bigdata01:8020/user_profile
data-warehouse.dbname=gmall2021
user-profile.dbname=user_profile2077#mysql配置
mysql.url=jdbc:mysql://127.0.0.1:3306/user_profile_manager_1009?characterEncoding=utf-8&useSSL=false
mysql.username=root
mysql.password=hike

4 DAO层

(1)TagInfoDAO

package com.hzy.userprofile.daoimport com.hzy.userprofile.bean.TagInfo
import com.hzy.userprofile.util.MySqlUtilobject TagInfoDAO {def getTagInfoByTaskId(taskId:String): TagInfo ={val tagInfoSql: String =s"""select id,tag_code,tag_name,| parent_tag_id,tag_type,tag_value_type,| tag_value_limit,tag_task_id,tag_comment,| create_time| from tag_info| where tag_task_id=$taskId""".stripMarginval tagInfoOpt: Option[TagInfo] =MySqlUtil.queryOne(tagInfoSql, classOf[TagInfo], true)var tagInfo: TagInfo = null;if (tagInfoOpt != None) {tagInfo = tagInfoOpt.get} else {throw new RuntimeException("no tag  for task_id  : "+taskId)}tagInfo}
}

(2)TaskInfoDAO

package com.hzy.userprofile.daoimport com.hzy.userprofile.bean.TaskInfo
import com.hzy.userprofile.util.MySqlUtilobject TaskInfoDAO {def getTaskInfo( taskId:String): TaskInfo ={val taskInfoSql: String =s"""select id,task_name,| task_status,task_comment,task_time ,| task_type,exec_type,main_class,file_id,| task_args,task_sql,task_exec_level,create_time| from task_info where id=$taskId""".stripMarginval taskInfoOpt: Option[TaskInfo] =MySqlUtil.queryOne(taskInfoSql, classOf[TaskInfo], true)var taskInfo: TaskInfo = null;if (taskInfoOpt != None) {taskInfo = taskInfoOpt.get} else {throw new RuntimeException("no task  for task_id  : "+taskId)}taskInfo}
}

(3)TaskTagRuleDAO

package com.hzy.userprofile.daoimport com.hzy.userprofile.bean.TaskTagRule
import com.hzy.userprofile.util.MySqlUtilobject TaskTagRuleDAO {def getTaskTagRuleListByTaskId(taskId:String): List[TaskTagRule] ={// 需两表的关联// task_tag_rule中的query_value为FMU,对应的sub_tag_id为8,9,10// 8,9,10没用,想要男,女,未知,所以需要将8,9,10换成标签的值// 作法:用8,9,10关联tag_info中的idval taskRuleSql: String =s"""select tr.id,tr.tag_id,tr.task_id,tr.query_value,| sub_tag_id,ti.tag_name as sub_tag_value| from task_tag_rule tr,tag_info ti| where tr.sub_tag_id=ti.id and   tr.task_id=$taskId""".stripMarginval taskTagRuleList: List[TaskTagRule] =MySqlUtil.queryList(taskRuleSql, classOf[TaskTagRule], true)taskTagRuleList}
}

(4)测试

在user-profile-task1009\task-sql\src\main\scala\com\hzy\userprofile\app\TaskSQLApp.scala完成DAO层的测试

传递args(0),args(1)的值,传递过程如下图:

添加三条语句,完成测试

println(tagInfo)
println(taskInfo)
println(taskTagRuleList)

运行结果

select id,tag_code,tag_name,parent_tag_id,tag_type,tag_value_type,tag_value_limit,tag_task_id,tag_comment,create_timefrom tag_infowhere tag_task_id=1
log4j:WARN No appenders could be found for logger (ru.yandex.clickhouse.ClickHouseDriver).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
select id,task_name,task_status,task_comment,task_time ,task_type,exec_type,main_class,file_id,task_args,task_sql,task_exec_level,create_timefrom task_info where id=1
//TagInfo
TagInfo(7,TG_BASE_PERSONA_GENDER,性别,null,5,1,3,null,null,1,null,2022-10-09 16:20:11.0,null)
//TaskInfo
TaskInfo(1,标签计算:性别,1,计算用户性别,02:40,TAG,SQL,null,null,--driver-memory=1G
--num-executor=3
--executor-memory=2G
--executor-cores=2
--conf spark.default.parallelism=12,select id as uid,if(gender is null, 'U',gender) as query_value from dim_user_info where dt='9999-99-99',100,null)
//TaskTagRule
List(TaskTagRule(1,7,1,F,8,男), TaskTagRule(2,7,1,M,9,女), TaskTagRule(3,7,1,U,10,未知))

至此,开发主线中的第一步【获得标签定义、标签任务的SQL、字标签的匹配规则】已经完成。

【用户画像】标签任务开发流程(源码之实体类、工具类、配置文件、DAO层)相关推荐

  1. 用户画像标签数据开发之标签相似度计算

    目录 0. 相关文章链接 1. 什么是标签相似度计算 2. 案例场景 3. 数据开发 注:此博文为根据 赵宏田 老师的 用户画像·方法论与工程化解决方案 一书读后笔记而来,仅供学习使用 0. 相关文章 ...

  2. 用户画像标签数据开发之用户特征库开发

    目录 0. 相关文章链接 1. 什么是用户特征库 2. 特征库规划 3. 数据开发 4. 其他特征库规划 注:此博文为根据 赵宏田 老师的 用户画像·方法论与工程化解决方案 一书读后笔记而来,仅供学习 ...

  3. 用户画像标签数据开发之组合标签计算

    目录 0. 相关文章链接 1. 什么是组合标签计算 2. 应用场景 3. 数据计算 注:此博文为根据 赵宏田 老师的 用户画像·方法论与工程化解决方案 一书读后笔记而来,仅供学习使用 0. 相关文章链 ...

  4. python用户画像_新闻个性化推荐系统源码之构建离线用户和文章特征

    我们完成了文章画像和用户画像的构建,画像数据主要是提供给召回阶段的各种召回算法使用.接下来,我们还要为排序阶段的各种排序模型做数据准备,通过特征工程将画像数据进一步加工为特征数据,以供排序模型直接使用 ...

  5. OpenJDK源码研究笔记(六)--观察者模式工具类(Observer和Observable)和应用示例

    2019独角兽企业重金招聘Python工程师标准>>> 本文主要讲解OpenJDK观察者模式的2个工具类,java.util.Observer观察者接口,java.util.Obse ...

  6. java 集合反射_关于granite源码包CollectionUtil集合工具类获取集合反射类型、实例化各种集合类型HashSet/ArrayList等...

    一.前言 基于granite源码包org.granite.util.CollectionUtil集合工具类,分别获取集合反射类型java.lang.reflect.Type.实例化newCollect ...

  7. java.util.list源码_关于fest-util源码包Collections集合工具类过滤、判空、格式化及复制克隆处理...

    一.前言 关于fest-util源码包org.fest.util.Collections集合处理类,实现对数组转换List序列集合.集合duplicatesFrom克隆复制.集合判空isEmpty.并 ...

  8. Go语言使用之JSO使用、源码解析和JSON工具类

    在go语言网络编程中,经常会有这样的需求:保存结构体和读取结构体数据.如果你使用redis数据库存储数据,你怎么做?Redis仅支持五种数据类型( String(字符串) .Hash (哈希).Lis ...

  9. 全网超详细!用户画像标签体系建设指南!

    大家好,最近工作之余看了很多用户画像的文章,要么描述浅显.要么相对片面,对于数据分析人员来说算是窥中豹管. 今天我将结合日常工作实践和理解,整理了一份用户画像的文章,内容偏向数据分析方法论,个人觉得这 ...

  10. 万字用户画像标签体系建设分析指南!

    转自:大数据梦想家 01 什么是用户画像 用户画像是指根据用户的属性.用户偏好.生活习惯.用户行为等信息而抽象出来的标签化用户模型.通俗说就是给用户打标签,而标签是通过对用户信息分析而来的高度精炼的特 ...

最新文章

  1. CentOS 安装Zabbix 手记
  2. 我的博客今天6岁298天了,我领取了元老博主徽章
  3. 计算机网络的网络层功能在内完成,计算机网络习题及答案
  4. linux服务器情况
  5. perl6 HTTP::UserAgent (2)
  6. clientX和clientY属性需要注意的地方
  7. Rivian计划在乔治亚州新增一个工厂
  8. BZOJ 4310 二分+SA+RMQ
  9. 工作分析文献综述_学术知识| 如何撰写文献综述
  10. python中字典的几个方法介绍
  11. 微信小程序实现底部导航栏自定义tabBar
  12. 矩阵迹的几何意义是什么?
  13. [zz] 导致你创业失败的18个错误 [2007-05-03]
  14. 优动漫PAINT是什么?有哪些功能和特色
  15. 【浏览器】解决火狐和Chrome上不了网,只有IE能上网的问题
  16. 国家著作权: DNA 计算公式, 肽展定理公式与 变嘧啶 推导.
  17. 写一个辨别素数的函数,在主函数输入一个整数,输出是否为素数信息。
  18. java 私有类_Java类属性的私有化
  19. 九宫格游戏c语言代码,C++代码实现寻找九宫格游戏所有答案
  20. Stata:系数为何不显著?GIF 演示 OLS 的性质

热门文章

  1. iOS开发——frame和bounds详解
  2. 工业物联网有什么特征
  3. 雷电2接口_代替你电脑的所有接口,世界最快的雷电3了解一下
  4. 工具类(Excel)[一]
  5. 达内php难吗,深圳达内php教学好吗 说说我学习的经历
  6. 大S产女获张兰连续两天探望 大赞儿媳妇是骄傲
  7. 苹果7 无线流量连接不上网络连接服务器,iPhone7连不上wifi无线网的四种解决方法...
  8. 45个android实例源码
  9. 2020计算机夏令营+预推免统计
  10. Linux服务器带宽占用高导致无法登录的处理经验分享