牛仔裤中的牛仔是什么

Q

牛仔裤中的牛仔是什么

A

“牛仔裤”一词源自英文单词“jeans”,最早可以追溯到1567年意大利热那亚港水手穿的一种粗帆布制作的裤子,当时水手们喜欢穿着这种粗糙而结实的布料做成的工作裤子,称之为Genoese, Genes,与Jeans有着相似的发音。1850年淘金热的浪潮下,移民到美国的巴伐利亚人李维·斯特劳斯创立了李维斯公司,该公司生产的帆布工装裤就是世人所知的牛仔裤的鼻祖。这种布料结实耐磨,十分适合应付繁重的日常劳作,受到当时矿工们的喜欢。
因此,牛仔裤中的“牛仔”并不是指牛,而是指穿着这种裤子的工人和冒险家
jeans

XML元素名称规范

背景

使用dom4j生成XML,期望结果
生成XML数据

1
<gNB间NG切换成功率(%)>100</gNB间NG切换成功率(%)>

但是抛错
1
2
3
4
5
6
7
8
9
java.lang.IllegalArgumentException: Illegal character in name: 'gNB间NG切换成功率(%)'.

at org.dom4j.QName.validateName(QName.java:340)
at org.dom4j.QName.<init>(QName.java:151)
at org.dom4j.tree.QNameCache.createQName(QNameCache.java:245)
at org.dom4j.tree.QNameCache.get(QNameCache.java:115)
at org.dom4j.DocumentFactory.createQName(DocumentFactory.java:191)
at org.dom4j.tree.AbstractElement.addElement(AbstractElement.java:760)
at Dom4jTest.test_AddTagBySpecial(Dom4jTest.java:25)

Read More

ThreadPoolExecutor学习

  • 创建线程的几种方式
    • Thread
    • Runnable
    • Callable(配合Future获取返回值)
    • 线程池
      • Executors
      • ThreadPoolExecutor
  • 线程池ThreadPoolExcecutor的7个参数
    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
    32
    33
    34
    /**
    * Creates a new {@code ThreadPoolExecutor} with the given initial
    * parameters.
    *
    * @param corePoolSize the number of threads to keep in the pool, even
    * if they are idle, unless {@code allowCoreThreadTimeOut} is set
    * @param maximumPoolSize the maximum number of threads to allow in the
    * pool
    * @param keepAliveTime when the number of threads is greater than
    * the core, this is the maximum time that excess idle threads
    * will wait for new tasks before terminating.
    * @param unit the time unit for the {@code keepAliveTime} argument
    * @param workQueue the queue to use for holding tasks before they are
    * executed. This queue will hold only the {@code Runnable}
    * tasks submitted by the {@code execute} method.
    * @param threadFactory the factory to use when the executor
    * creates a new thread
    * @param handler the handler to use when execution is blocked
    * because the thread bounds and queue capacities are reached
    * @throws IllegalArgumentException if one of the following holds:<br>
    * {@code corePoolSize < 0}<br>
    * {@code keepAliveTime < 0}<br>
    * {@code maximumPoolSize <= 0}<br>
    * {@code maximumPoolSize < corePoolSize}
    * @throws NullPointerException if {@code workQueue}
    * or {@code threadFactory} or {@code handler} is null
    */
    public ThreadPoolExecutor(int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    ThreadFactory threadFactory,
    RejectedExecutionHandler handler)
    • corePoolSize(核心线程数)
    • maximumPoolSize(最大线程数)
    • keepAliveTime、unit(最大空闲时间)
    • workQueue(阻塞队列)
    • threadFactory(线程工厂,为线程自定义名称)
    • handler(拒绝策略)
  • 线程池执行流程

Read More

Facebook广告中使用Deferred Deep Link

在运营时,学习使用了App Link和Deep Link,之前也使用了Firebase中的Dynamic Links在用户未安装App时跳转至Google Play安装后再打开仍然能获取到链接内容,带用户到推荐的个性化页面。
后面由于运营需要在Facebook上做推广,需要接入Meta的Deep Link
运营时有3个场景,我们的App,以下简称A

  1. 用户已安装A,点击Facebook广告链接,正常打开A并跳转至推广页面
  2. 用户未安装A,点击Facebook广告链接,打开Google play store,下载安装,并在Google play store中点击打开,正常打开A并跳转至推广页面
  3. 用户未安装A,点击Facebook广告链接,打开Google play store,下载安装,回到桌面点击A,正常打开A并跳转至推广页面
    实现1,只需要实现Meta中的Deep Link
    实现2、3则需要在实现Deep Link的基础外加上Deferred Deep Link

Read More

不动态创建链接情况下在Firebase Dynamic Link获取动态参数

在使用Firebase的Dynamic Links做运营时,需要在链接中带去不同的参数,APP做不同的响应。如,在链接中带商品ID,用户点击不同链接进入不同商品详情页。Firebase中有两种方法可以实现。
1、创建动态链接
创建动态链接-简介
2、通过动态链接参数来实现不创建动态链接APP接收自定义参数目的。缺点就是短链接变成了长链接。
下面看看做实验的demo
这是之前建立的链接
链接详情

Read More

如何找出so依赖来源

问题

上架Google Play时提示引用了有缺陷的OpenSSL版本
缺陷的库

解决思路

  • 找出该so属于哪个库
  • 升级或如何排除该so

找出so属于哪个库

在app下的build.gradle中添加如下代码

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
//列出所有包含有so文件的库信息
tasks.whenTaskAdded { task ->
if (task.name.contains("DebugNativeLibs")) {
task.doFirst {
println("------------------- find so files start -------------------")

it.inputs.files.each { file ->
printDir(new File(file.absolutePath))
}

println("------------------- find so files end -------------------")
}
}
}

def printDir(File file) {
if (file != null) {
if (file.isDirectory()) {
file.listFiles().each {
printDir(it)
}
} else if (file.absolutePath.endsWith(".so")) {
println "find so file: $file.absolutePath"
}
}
}

Read More

表达式引擎预研

背景

最后业务有需求需要动态计算表达式,基于公式对某些值进行再加工计算。所以对表达式引擎进行一个简单的了解。
表达式引擎就是为了表达式的动态求值计算。
通常对于各个类库对比,我们需要看厂商、License、社区活跃度、优缺点等来判断其符合的使用场景,最终决定应该用哪个。
由于时间较紧,只做简单收集,在项目中本已使用AviatorScript的情况下就选择了它。

特性对比

AviatorScript Groovy SpEL QLExpress
Version 5.3.2 4.0.4 5.3.22 3.3.0
厂商 killme2008 Apache Spring alibaba
License GPL V3 Apache 2 License Apache License 2.0 Apache License 2.0
Language 基于Java 基于Java Java Java
优点 高性能
轻量级
Flat learning curve
Powerful features
Smooth Java integration
Domain-Specific Languages
Vibrant and rich ecosystem
Scripting and testing glue
线程安全
高性能
弱类型脚本语言
安全控制
代码精简

还有OGNLDroolsEasyRules

另外MVELIKExpression很久未更新,不列

浏览器打开图片链接时直接显示或下载到底怎么回事

最近瞎JB搞了一通,各个项目都是喊组装上就交付,难以有时间学习总结,简直违反程序员的基本原则。很多时候已经忘记踩了哪些坑,如何解决的了。

问题

图片上传至阿里云OSS生成链接在浏览器中打开是直接下载文件,而需求需要打开图片而非下载。

常用方式

浏览器中的图片,通常印象中,前端上传文件获取url,终端当然是下载再展示。浏览器端都是img标签展示

1
<img src="/css/images/favicon.png"/>

下载图片及附件时都是右键保存或者点击按钮下载写入文件流中。
最近的需求中提到上传的图片生成的url,在浏览器中是打开而非下载文件 。我们正常上传到我们服务器上的是没问题的。这个问题出在阿里云OSS上?到底要怎么玩?

就经验来讲肯定是响应头header的问题。Android有类似的机制,view-type啥的,你是直接在别的应用中打开,还是怎么操作。
对比下载和打开图片两种不同链接

Read More