官网文档地址:获取小程序码
package test;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
/**
* @description:
* @author: Mr.Fang
* @create: 2023-04-03 17:06
**/
public class WxUtils {
/**
* description: 获取token,返回结果为 JSON 自行转 map
* create by: Mr.Fang
*
* @return: java.lang.String
* @date: 2023/4/3 17:46
*/
public String getToken() throws IOException {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
Map<String, Object> params = new HashMap<>();
params.put("appid", "appid");
params.put("secret", "secret");
params.put("grant_type", "client_credential");
String url = handleParams("http://api.weixin.qq.com/cgi-bin/token", params);
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity(); // 响应结果
return EntityUtils.toString(entity, CharSetType.UTF8.getType());
}
/**
* description: 对象转 字符串
* create by: Mr.Fang
*
* @param obj
* @return: java.lang.String
* @date: 2023/4/3 17:45
*/
public String objToStr(Object obj) {
ObjectMapper objectMapper = new ObjectMapper();
if (Objects.nonNull(obj)) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
return null;
}
/**
* description: 字符串 转 对象转
* create by: Mr.Fang
*
* @param jsonStr
* @param objClass
* @return: java.lang.String
* @date: 2023/4/3 17:45
*/
public <T> T strToObj(String jsonStr, Class<T> objClass) {
ObjectMapper objectMapper = new ObjectMapper();
try {
T t = objectMapper.readValue(jsonStr, objClass);
return t;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* description: 生成小程序码
* create by: Mr.Fang
*
* @param scene 携带参数
* @param page 页面路径
* @param token token
* @param path 保存路径
* @return: java.lang.String
* @date: 2023/5/11 14:22
*/
public String appletQR(String scene, String page, String token, String path) throws IOException {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
Map<String, Object> params = new HashMap<>();
params.put("scene", scene);
params.put("page", page); //developer为开发版;trial为体验版;formal为正式版;默认为正式版
params.put("env_version", "develop"); //要打开的小程序版本。正式版为 "release",体验版为 "trial",开发版为 "develop"。默认是正式版。
HttpPost httpPost = new HttpPost("http://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + token);
httpPost.addHeader("ContentTyp", "application/json");
// 参数转 JSON 格式
String json = objToStr(params);
StringEntity stringEntity = new StringEntity(json, CharSetType.UTF8.getType());
stringEntity.setContentEncoding(CharSetType.UTF8.getType());
httpPost.setEntity(stringEntity);
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity(); // 响应结果
byte[] data;
try {
data = readInputStream(entity.getContent());
} catch (Exception e) {
e.printStackTrace();
return null;
}
if (data.length < 100) { // 异常
String error = new String(data);
return null;
}
String fileName = UUID.randomUUID().toString().replaceAll("-", "") + ".png";
String filePath = path + File.separator + fileName;
// 创建文件
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(filePath);
fileOutputStream.write(data);
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
// 释放资源
try {
assert fileOutputStream != null;
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return fileName;
}
/**
* description: 输入流转字节数组
* create by: Mr.Fang
*
* @param inStream 输入流
* @return: byte[]
* @date: 2023/5/11 11:52
*/
public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
// 创建一个Buffer字符串
byte[] buffer = new byte[1024];
// 每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
// 使用一个输入流从buffer里把数据读取出来
while ((len = inStream.read(buffer)) != -1) {
// 用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
// 关闭输入流
inStream.close();
// 把outStream里的数据写入内存
return outStream.toByteArray();
}
public static void main(String[] args) throws IOException {
WxUtils wxUtils = new WxUtils();
// 获取 token
String token = wxUtils.getToken();
// 字符串转 map 对象
Map map = wxUtils.strToObj(token, Map.class);
// 生成小程序码
String path = wxUtils.appletQR("2023", "pages/index/index", map.get("access_token").toString(), System.getProperty("user.dir") + File.separator);
System.out.println(path);
}
}
项目根目录生成小程序码
本文来自博客园,作者:天葬,转载请注明原文链接:http://www.cnblogs.com/bxmm/p/17391023.html
“protobuf是google的一个开源项目,简单的来说,它比Json,Xml产生的数据更小,更快速,缺点就是可读可写性差。游戏开发的话一般在网络通讯中会使用。” 以下来自官网的介绍: protocolbuffers是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。 ProtocolBuffers是一种灵活,高效,自动化机制的结构数据序列化方法-可类比XML,但是比XML更小(3~10倍)、更快(20~100倍)、更为简单。 你可以定义数据的结构,然后使用特殊生成的源代码轻松的在各种数据流中使用各种语言进行编写和读取结构数据。你甚至可以更新数据结构,而不破坏由旧数据结构编译的已部署程序。01—VisuslStudio首先,我们新建一个控制台项目,下载protobuf-net的Ngut包,下载的方法依次点击工具->Ngut包管理器->管理解决方案的Ngut程序包:并在搜索框中搜索:“protobuf-net”.选择好之后,目光转到右边的选项那: 选择你的项目,然后点击安装,等待一会即可安装完成。然后打开program.cs文件
这天,我还在安详的看书学习,面试官的电话突然找我,问到:你懂Condition接口嘛?不懂今天就结束了哦。 听到是个妹纸声音来了,我立马也精神了起来,说到: Condition实现了管程里面的条件变量。Java内置的管程只有一个条件变量,而Lock和Condition二人组实现的管程支持多个条件变量。因为这样可以使得代码可读性更好,实现也更容易。实现一个阻塞队列,就需要两个条件变量。可爱的面试官又真诚发问到:那如何利用两个条件变量实现一个阻塞队列呢? 一个阻塞队列,至少有两个条件变量:队列不空 因为空队列没有元素,所以不可以做出队操作队列不满 因为队列如果已满,则不可再做入队操作Lock和Condition实现的管程,线程的等待和通知需要调用await()、signal()/signalAll(),它们的语义和wait()、notify()/notifyAll()相同。Lock&Condition实现的管程 只能使用await()、signal()/signalAll()synchronized实现的管程 才能使用wait()、notify()/notifyAll()如果在Lo
1保存成word格式第一步保存为md格式第二步通过docker界面转化为word如下:pandocSRVVWebServices-s-ofile.docx 第1处:上面导出的md文件所在的目录第2处:上面导出的md文件名第3处:保存的word文件名直接运行,其他地方不要改动补充知识:jupyternotebook更改浏览器时候提示GenericBrowserisnotdifined想修改下,Jupyternotebook配置的浏览器,网上搜了下方法直接试了。importwebbrowser webbrowser.register(‘chrome’,None,GenericBrowser(u’C:\\ProgramFiles(x86)\\Google\\Chrome\\Application\\chrome.exe’)) c.NotebookApp.browser=‘chrome’ 直接提示Error打开的还是默认浏览器,而且无法显示页面。具体提示是GenericBrowserisnotdifined。这个东西没有定义。仔细搜了下这个东东,找不到更详细的信息。后来猜测是引用问题,又翻阅了
1Numerai想必很多人还不知道Numerai吧,有志于从事量化方向的同学可以重点关注下。Numerai是一家初创公司,以举办专业数据锦标赛(类似kaggle)为其对冲基金寻找最佳交易策略而闻名。同时,它能将世界各地数据学家的股市预测模型“众包”出去。同时,Numerai创建了自己的加密货币,名为Numeraire(NMR)。近日,Numerai通过ICO完成了300万美元融资,Placeholder、UnionSquare等公司参投。https://numer.ai/homepage/纵观大多数华尔街对冲基金的模型,开放、协作绝不是它们的核心。电影《华尔街》充分描述了GordonGekko的贪婪,《华尔街之狼》更是展现了权利和金钱所带来的堕落和颓废,揭露了那些自负的资本家鲜为人知的一面。Numerai的创始人兼首席执行官RichardCraib想要改变这一切。Craib想要为对冲基金创造一个更加开放和去中心化的环境。这个环节不会限制你对数据的访问,在与全球数据科学家分享之前,Craib会对这些数据进行加密,这能防止数据被窃取。这些数据科学家会利用这些共享的信息为对冲基金打造预测模
概念(1)变量的作用域不带有关键字var的变量会成为全局变量;在函数中使用关键字var声明的变量是局部变量。局部变量只有在函数内部才能访问到,在函数外面是访问不到的。但在函数内部可以通过作用域链一直向上搜索直到全局对象,也就是说,函数内部可以访问函数外部的变量。(2)变量的生存周期对于全局变量,其生存周期是永久的,除非主动销毁这个全局变量;而对于在函数内用关键字var声明的局部变量,当退出函数时,这些局部变量会随着函数调用结束而被销毁。varfunc=function(){ vari=1; alert(i);//输出:1 }; alert(i);//报错:iisnotdefind.复制示例varfunc=function(){ vari=1; returnfunction(){ alert(i); i++; } }; varf1=func(); f1();//输出:1 f1();//输出:2 varf2=func(); f2();//输出:1 f2();//输出:2复制从闭包的一个经典应用谈起<div>0</div> <div>1</div&g
目录x64汇编第四讲,c/C++中调用x64汇编一丶简介1.说明二丶C/C++调用asm64.asm函数.1.配置asm参与生成2.给Asm文件添加函数代码3.C/C++调用asm的函数x64汇编第四讲,c/C++中调用x64汇编一丶简介1.说明在x86下,我们的C/C++调用汇编可以直接__asm进行内联. 或者也可以直接静态链接具体详情可以参考以前博客:https://www.cnblogs.com/iBinary/p/7555503.html其实在我们x64下跟x32调用一样.只不过不支持内联汇编了.还是支持你编译成obj的方式进行调用.你声明一下就可以使用了.现在我们用新的方法.直接编写一个x64ASM文件即可.二丶C/C++调用asm64.asm函数.1.配置asm参与生成首先我们创建一个C/C++空项目.使用VS创建.这个应该很简单.不在截图了. 然后创建一个.c或者.cpp文件.里面先按照征程写法,编写你的程序. 如下: 可以正常执行然后我们添加一个.asm文件的后缀名.这个文件跟添加.cpp文件一样.自己更改为.asm即可.如下: 最重要的一步 你有这个文件,但是不能参
「调用链监控」是在微服务兴起后才有的一种新流行的监控模式。因为在我们传统单体应用的项目中,不存在服务链/调用链的概念,所以也就根本没有调用链监控的需求了。 当我们开始微服务架构之后,我们的很多服务变成分布式的了,并且我们对服务进行了拆分,拆分之后,用户的一个请求进来,会依次经过不同的服务节点进行处理,处理完成后再返回结果给用户。那么在整个处理的链条中,如果有任何一个节点出现了延迟或者问题,都有可能导致最终的结果出现异常,有的时候不同的服务节点甚至是由不同的团队开发的、部署在不同的服务器上,那么在这么错综复杂的环境下,我们想要排查出是链条中的具体哪个服务节点出了问题,其实并不容易。因此大家就想到了一个办法,将这个请求经过的每一个节点都记录下来,形成一个完整的调用链监控系统,那么一旦发生请求调用异常的情况,只需要去排查这个调用链日志就能很清楚看到出错的环节在哪儿。一、为什么需要「调用链监控」?「调用链监控」是在微服务架构中非常重要的一环。它除了能帮助我们定位问题以外,还能帮助项目成员清晰的去了解项目部署结构,毕竟一个几十上百的微服务,相信在运行时间久了之后,项目的结构很可能就是下面图片这样
内容来源:2018年04月21日,AI教育求职平台景略集智创始人王文凯在“百度深度学习公开课·北京站:AI工程师的快速进阶之路”进行《目标检测面面观》演讲分享。IT大咖说(微信id:itdakashuo)作为独家视频合作方,经主办方和讲者审阅授权发布。阅读字数:4339|11分钟阅读摘要本次演讲主要介绍视觉识别领域中目标检测的相关技术,对其中各种不同的检测方法进行解析和对比。获取嘉宾演讲视频及PPT,扫一扫下方二维码即可。 VisualRecognition最简单的视觉识别是根据图片中的物体对图片进行分类,典型的就是判断一张照片是猫还是狗。再进一步不仅要识别图片中物体,还要对它进行定位。实际工程中,图片一般会同时存在多个物体,面对这种复杂场景需要应用目标检测,同时包含分类和定位。比目标检测更深入的是语义分割,从上图可以看到目标检测只是简单的框出了物体,而语义分析会挖掘出图像中更深层次的信息。Classification对分类领域稍有熟悉的朋友可能都知道MNIST(手写数字)数据集,它被称为DeepLearning中的helloworld,主流的深度学习框架都会提供该数据集的相应的接口。
背景随着项目的发展,许多项目中H5(特别是微信平台内)以及小程序占比逐渐增多,因此快速建设相关的自动化来提高项目的效率和质量成为了许多项目中的重中之重。然而目前市面上能完美支持微信H5和小程序测试的测试工具是缺失的。因此我们展开了求索之路,并且成功研发了FAT框架,来解决这个难题。想了解我们是如何解决H5/小程序UI自动化测试难题的看官们,请听我慢慢讲来。调研之路首先团队先对市面上流行的测试工具,包括Uiautomator、Appium进行了快速的调研,调研结果如下:其中Appium看起来是支持H5的,可是在实际操作使用中,切换页面需要重新建立chomedriver通信,控件识别耗时长,稳定性差,严重影响自动化的维护成本,而小程序更是无法支持。调研的结论让人沮丧,现有工具都不能很好的支持小程序测试。俗话说只要思想不滑坡,办法总比困难多,没有什么可以阻止我们前进的道路!终于在一篇文章中得到了启发,关键技术点的就是—Chromedebuggingprotocol。撸起袖子加油干在得到关键信息之后,团队决定自己开搞,立志于提供微信内H5/小程序UI自动化的统一解决方案,于是,FAT(Fast
#include<pthread.h> //线程 intpthread_create(pthread_t*tid,constpthread_attr_t*attr,void*(*func)(void*),void*arg); intpthread_join(pthread_t*tid,void**status); pthread_tpthread_self(void); intpthread_detach(pthread_ttid); voidpthread_exit(void*status); //线程特定数据 intpthread_once(pthread_once_t*onceptr/*PTHREAD_ONCE_INIT*/,void(*init)(void)); intpthread_key_create(pthread_key_t*keyptr,void(*destructor)(void*value)); void*pthread_getspecific(pthread_key_tkey); intpthread_setspecific(pthread_ke
本文66页干货来自西安建筑科技大学的郑晓伟博士及其团队成员,全面介绍了该团队在新数据环境下的城市规划实践,通过8个具体案例在8大领域展示了规划实践的应用体系:1结构优化类基于网络开放数据的西安城市公共中心体系优化2职住平衡类基于人口热力数据的西安中心城区职住关系研究3形态测度类城市能耗数据与可持续低碳式城市形态关系探索4设施选址类多源数据驱动下西安中心城区公共厕所布点选址5活力监测类春节期间西安城市运行活力监测大数据评价分析6库存识别类存量时代西安城市商业与居住建筑库存识别研究7腹地划分类基于手机信令数据的大西安城市群腹地划分研究8存量设计类多源数据支撑下西安明城区更新与改造城市设计作者简介郑晓伟博士中国城市科学研究会城市大数据专业委员会委员西安建筑科技大学城乡规划大数据应用技术实验中心(筹)
工作中我相信你一定会遇到处理数字证书的时候。各种平台,各种语言,它们采用的证书格式与标准都不相同,多多少少存在一些差异。实际上证书仍然是那个证书,只是格式发生了变化。公私钥分开存储公私钥合并为一个文件有些采用二进制文件有些事二进制文件做了BASE64编码有些证书做了签名有些证书加入了密码不同组织有不同的编码。例如微软喜欢使用x509 下面内容节节选自《NetkillerCryptography手札》接下来几天我们将讨论密钥证书相关话题。文章出处:http://www.netkiller.cn/cryptography/index.html7.7.证书转换 PKCS全称是Public-KeyCryptographyStandards,是由RSA实验室与其它安全系统开发商为促进公钥密码的发展而制订的一系列标准,PKCS目前共发布过15个标准。常用的有: PKCS#7CryptographicMessageSyntaxStandard PKCS#10CertificationRequestStandard PKCS#12PersonalInformationExchangeSyntaxSt
简介Swagger是一款restful接口的文档在线自动生产加功能测试的软件。目的是为了减少与其他团队的沟通成本,因此会试用swagger构建restfulapi文档来描述所有的接口信息。官方网站https://swagger.io/swagger信息泄露路径/swagger/ /api/swagger/ /swagger/ui/ /api/swagger/ui/ /swagger-ui.html/ /api/swagger-ui.html/ /user/swagger-ui.html/ /swagger/ui/ /api/swagger/ui/ /libs/swaggerui/ /api/swaggerui/ /swagger-resources/configuration/ui/ /swagger-resources/configuration/security/复制
备忘录模式(MementoPattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。 介绍 意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。 主要解决:所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。 何时使用:很多时候我们总是需要记录一个对象的内部状态,这样做的目的就是为了允许用户取消不确定或者错误的操作,能够恢复到他原先的状态,使得他有"后悔药"可吃。 如何解决:通过一个备忘录类专门存储对象状态。 关键代码:客户不与备忘录类耦合,与备忘录管理类耦合。 应用实例: 1、后悔药。2、打游戏时的存档。3、Windows里的ctri+z。4、IE中的后退。4、数据库的事务管理。 优点: 1、给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。2、实现了信息的封装,使得用户不需要关心状态的保存细节。 缺点:消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存
【题目描述】 小N,小A,小T又大了一岁了。 现在,他们已经是高二年级的学生了。众所周知,高二的小朋友是要进行文理科分班考试的,这样子的话,三个好朋友说不定就会不分在一个班。 于是三个人决定,都考平均分。。。。。。 当然这不是我们关心的问题。 年级主任Qian,表示分班真的是很头痛。 校长XXY给Qian的分班条件是这样子。 首先由M个学生,分数从高到低已经排序好了。 其次要分成至多N个班。 每个班必须要有至少A个至多B个小朋友。 一个班的学生,他们的分数必须是连在一起的。也就是说,如果第3个小朋友和第5个小朋友在一间教室,第4个小朋友也必须和他们在一起。 最操蛋的是。。。XXY还给出了一个评定分班好不好的标准。 每个学生有一个不知道啥的敏感指数,X[i],1<=i<=M。并且,有一个变量Average=。为了方便计算,Average取下整,注意是先加起来再除,不是每次除再加。 每个教室有一个舒适程度G[i]。而g[i]表示的是第i个小朋友在哪个教室。 现在XXY要求最小化评价指数=∑(每个同学敏感指数-Average)^2*该同学分到班级的舒适度Gi 【输入格式】 本题目
Spring创建bean的几种方式 在XML配置文件中,通过bean标签创建bean,然后再通过spring容器进行管理 创建xml配置文件定义bean 一、通过构造函数创建 1<?xmlversion="1.0"encoding="UTF-8"?> 2<beansxmlns="http://www.springframework.org/schema/beans" 3xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"> 5 6<beanid="User"class="com.example.springioc.User"/> 7</beans>复制 创建bean类 1publicclassUse
闲着没事采集了一组能量轨迹数据集,可以用来练习一下侧信道,采集情况如下: 示波器:梦圆实验室,DSCope20 采样率:200Mhz 硬件平台:arduinoUNO 使用代码如下: #include<AESLib.h> voidsetup(){ //putyoursetupcodehere,torunonce: //Serial.begin(57600); pinMode(12,OUTPUT); } voidloop(){ uint8_tkey[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; chardata[]="0123456789012345"; digitalWrite(12,HIGH); aes256_enc_single(key,data); digitalWrite(12,LOW); //Serial.print("encrypted:"); //Serial.println(data); //aes256_dec_si
理解Docker(2):Docker镜像 本系列文章将介绍Docker的有关知识: (1)Docker安装及基本用法 (2)Docker镜像 (3)Docker容器的隔离性-使用Linuxnamespace隔离容器的运行环境 (4)Docker容器的隔离性-使用cgroups限制容器使用的资源 (5)Docker网络 对于每个软件,除了它自身的代码以外,它的运行还需要有一个运行环境和依赖。不管这个软件是象往常一样运行在物理机或者虚机之中,还是运行在现在的容器之中,这些都是不变的。在传统环境中,软件在运行之前也需要经过代码开发->运行环境准备->安装软件->运行软件等环节,在容器环境中,中间的两个环节被镜像制作过程替代了。也就是说,镜像的制作也包括运行环境准备和安装软件等两个主要环节,以及一些其他环节。因此,Docker容器镜像其实并没有什么新的理论,只是这过程有了新的方式而已。 镜像(image)是动态的容器的静态表示(specification),包括容器所要运行的应用代码以及运行时的配置。Docker镜像包括一个
P1972[SDOI2009]HH的项链 题目背景 无 题目描述 HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此,他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答……因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。 输入输出格式 输入格式: 第一行:一个整数N,表示项链的长度。 第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。 第三行:一个整数M,表示HH询问的个数。 接下来M行:每行两个整数,L和R(1≤L≤R≤N),表示询问的区间。 输出格式: M行,每行一个整数,依次表示询问对应的答案。 输入输出样例 输入样例#1: 6 123435 3 12 35 26 复制 输出样例#1: 2 2 4复制 说明 数据范围: 对于100%的数据,N<=500000,M<=200000。 ——————————————————
是否记得这样的试题?用一套同样的HTML结构,生成不同的视觉效果。CSS的最大好处就是,灵活。比如同样的HTML结构,可以实现不同的外观;又比如,同样的外观,可以用不同的方式不实现。但灵活的同时也给我们带来麻烦。团队协作时,大家的编码风格各异,其他人要看懂/debug的成本也因此提高。这时,我们需要一个规范,一个像红灯亮起我们就不能擅闯的规范。 在Alipay前端,Alice框架有这样一套规范,让大家的协作更方便。这套规范基于Alice,属于Alice的一部分。其最基本的原则是,同样的结构,产出不同的视觉效果。 注:所有样式的创建,都必须基于 CSS规范 进行 http://blog.csdn.net/shoyer/article/details/8300442 一、Alice设计模式 Alice的设计起源于支付宝的pa.css文件。由于这个文件被多系统引用,没有人敢随便改动里面的内容,所以只能不断往里面添加内容,导致了这个文件体积变得非常大。所以,亟待重构。在尝试重构后,发现了重构不是我们真正想要的,因些主要从两个方面来构建Alice: 减少依赖,避免耦合 统