Guava LoadingCache不能缓存null值 | 木杉的博客
测试的时候发现项目中的LoadingCache没有刷新,但是明明调用了refresh方法了。后来发现LoadingCache是不支持缓存null值的,如果load回调方法返回null,则在get的时候会抛出异常。
Read full article from Guava LoadingCache不能缓存null值 | 木杉的博客
Guava LoadingCache不能缓存null值 | 木杉的博客
测试的时候发现项目中的LoadingCache没有刷新,但是明明调用了refresh方法了。后来发现LoadingCache是不支持缓存null值的,如果load回调方法返回null,则在get的时候会抛出异常。
Read full article from Guava LoadingCache不能缓存null值 | 木杉的博客
In this tutorial, we'll take a look at the Guava Cache implementation – basic usage, eviction policies, refreshing the cache and some interesting bulk operations.
Finally, we will take a look at the using the removal notifications the cache is able to send out.
Read full article from Guava Cache | Baeldung
Arrays of Wisdom of the Ancients
The Java Language and JDK Class Library have two distinct, yet connected, ways to group elements: arrays and Collections. There are pros and cons for using either one, so both are prevalent in real programs. To aid conversion between the two, there are standard methods to make a reference array appear as a Collection (e.g. Arrays.asList
), and to copy from Collection to array (e.g. several Collection.toArray
methods). In this post, we will try to answer a controversial question: which toArray
conversion pattern is faster?
The post uses JMH as the research crucible. If you haven't learned about it yet, and/or haven't looked through the JMH samples, I suggest you do that before reading the rest of this post for the best experience. Some x86 assembly knowledge is also helpful, though not strictly required.
Read full article from Arrays of Wisdom of the Ancients
Java's System.identityHashCode | JavaWorld
The java.lang.System class provides many useful general utilities including handles to the standard output stream, the standard input stream, the standard error stream, and the console as well as methods for obtaining the current time in milliseconds, defined properties, and environmental variables. In this blog post, I briefly look at the System.identityHashCode(Object) method.
The Javadoc documentation for System.identityHashCode(Object) states:
Read full article from Java's System.identityHashCode | JavaWorld
Call hierarchy in Eclipse and IntelliJ | XENOVATION
We have used our favorite IDEs (IntelliJ and Eclipse) to examine the call hierarchy tree of the source code in order to get a tree view of all the callers and callees of the selected method. in this article we described in detail how we did it.
Read full article from Call hierarchy in Eclipse and IntelliJ | XENOVATION
java - Why are static imports of static methods with same names legal? - Stack Overflow
The ambiguity of the static imports of methods could be resolved at the point of the method invocation.
For example if you had a static import for two methods that look like this:
void frobnicate(int i); // and void frobnicate(boolean b);
Then you could import and use both, because the compiler could tell which one to use, based on the arguments you pass in (frobnicate(1)
calls the first one, frobnicate(true)
calls the second one).
With classes, that's not possible: Foobar a;
alone is not sufficient to tell you which of the two Foobar
classes you want.
Also note that a single static import can import multiple names. According to the relevant section of the JLS (emphasis mine):
A single-static-import declaration imports all accessible static members with a given simple name from a type.
For example if the two frobnicate
methods above where located in the same class, a single static
import could import them both.
Read full article from java - Why are static imports of static methods with same names legal? - Stack Overflow
How Re2 Shattered My Bottleneck
One pleasant morning I got to work, thinking this day couldn't get any better. But as Murphy would have it, there was my boss walking frantically toward me.
It turned out that almost over night one of the main data pipeline systems had become a major bottleneck for the company, and a solution was needed, Fast!
Usually in a startup, let alone a company moving as fast as Taboola, these things can occur on a weekly basis.
I needed to find some quick wins to relieve some of the bottlenecks inside the system.
Luckily Re2 was there to the rescue – in this post I will share how to find the bottlenecks using Gprof2dot beautiful image rendering, and of course, what Re2 is and how to use it.
* Note that this article addresses a pain I had in a Python framework, but because there are Re2 implementations to all major languages you should still find value reading this article.
Step one: Recognize were it hurts the most
Step two: Reduce the pain
Step three: Iterate back to step one until you get the desired result
Read full article from How Re2 Shattered My Bottleneck
regex - java escape parenthesis - Stack Overflow
Use a backslash: \)
. Parens must be escaped because they can be used to group parts of the regex.
Read full article from regex - java escape parenthesis - Stack Overflow
Java Regex - Capturing Groups - Tutorialspoint
Capturing groups are a way to treat multiple characters as a single unit. They are created by placing the characters to be grouped inside a set of parentheses. For example, the regular expression (dog) creates a single group containing the letters "d", "o", and "g".
Capturing groups are numbered by counting their opening parentheses from the left to the right. In the expression ((A)(B(C))), for example, there are four such groups −
To find out how many groups are present in the expression, call the groupCount method on a matcher object. The groupCount method returns an int showing the number of capturing groups present in the matcher's pattern.
There is also a special group, group 0, which always represents the entire expression. This group is not included in the total reported by groupCount.
Read full article from Java Regex - Capturing Groups - Tutorialspoint
bash – 为什么我不能用";"来调用两个别名? - 代码日志
简单地通过用别名替换别名来扩展别名(作为标记列表,而不是字符串,这基本上等同于获取字符串并在末尾添加空格).所以停止; true扩展为cd $HOME/website; make website_stop; make backend_stop; ; true ^^^
由于shell语法中不能有两个连续的分号,这是一个语法错误.
你可以删除;,这将使stopdev; startev工作,但它并不好,因为你传递给stopdev的任何参数都将被传递给make backend_stop,这可能是不可取的.
你应该把它变成一个功能.另外,如果cd命令失败,请不要运行make命令.
Read full article from bash – 为什么我不能用";"来调用两个别名? - 代码日志
bash – 为什么我不能用";"来调用两个别名? - 代码日志
当我尝试使用;结合两个正常命令;字符(例如ls; cd)它工作正常.但是,我创建了两个别名(stopdev和startdev),如果我尝试将它们组合起来:stopdev; startdev
或者即使我只是尝试在一个后面添加一个分号:
stopdev;
我收到语法错误:
bash: syntax error near unexpected token `;'
如果我使用&&我也会遇到同样的问题:
stopdev && startdev
bash: syntax error near unexpected token `&&'
我对此感到困惑,因为我认为别名就像任何其他命令一样……但显然它们不是.
那么,有两个问题:
>为什么要使用;或者&&别名调用无效?
>有没有办法(除了创建一个stopstartdev别名)轻松地将这两个命令一起运行?
Read full article from bash – 为什么我不能用";"来调用两个别名? - 代码日志
Protocol Buffers provide an efficient way to encode structured data for serialization. The language's basic organizational type is a message, which can be thought of as a C-style structure. It is named and contains some number of fields. Messages can also be extended, but the method by which this is accomplished differs from familiar C++ or Java-style inheritance. Instead, message extension is implemented by reserving some number of field indices in the base message for use by the extending messages.
Read full article from Protocol Buffer Polymorphism
Protobuf is really missing inheritance · Issue #5645 · protocolbuffers/protobuf · GitHub
GRPC is not doing "favor composition over inheritance" pattern, it's applying "remove inheritance" pattern. :D
There are cases when inheritance is more suitable. Just because it's a good practice to "favor somehing", it doesn't mean it should be removed completely (or not implemented at all).
Read full article from Protobuf is really missing inheritance · Issue #5645 · protocolbuffers/protobuf · GitHub
Protocol Buffer Basics: Java | Protocol Buffers | Google Developers
You'll find a complete guide to writing .proto
files – including all the possible field types – in the Protocol Buffer Language Guide. Don't go looking for facilities similar to class inheritance, though – protocol buffers don't do that.
Read full article from Protocol Buffer Basics: Java | Protocol Buffers | Google Developers
java - Inheritance in protocol buffers - Stack Overflow
Protocol Buffers does not support inheritance. Instead, consider using composition:
message Foo { Bar bar = 1; string id = 2; }
However, that said, there is a trick you can use which is like inheritance -- but which is an ugly hack, so you should only use it with care. If you define your message types like:
message Bar { string name = 1; } message Foo { string name = 1; string id = 2; }
These two types are compatible, because Foo
contains a superset of the fields of Bar
. This means if you have an encoded message of one type, you can decode it as the other type. If you try to decode a Bar
as type Foo
, the field id
will not be set (and will get its default value). If you decode a Foo
as type Bar
, the field id
will be ignored. (Notice that these are the same rules that apply when adding new fields to a type over time.)
You can possibly use this to implement something like inheritance, by having several types all of which contain a copy of the fields of the "superclass". However, there are a couple big problems with this approach:
Foo
to type Bar
, you have to serialize and re-parse; you can't just cast. This can be inefficient.Read full article from java - Inheritance in protocol buffers - Stack Overflow
How to adjust Gmail for a smaller screen - TechRepublic
Gmail has recently undergone a number of changes--all of which are for the better. These additions are long overdue and add features to the venerable email service that many users will immediately want to employ.
Although not every feature is a deal maker or breaker, there are some that make using Gmail a bit easier. One feature allows you to collapse the left navigation to give you more room for what you need to do, which is manage your email. This is a real boon to anyone who uses Gmail on a smaller screen and needs as much space for productivity as possible. You won't find this feature on the mobile app. It's desktop Gmail only, and once you use it you won't go back.
Read full article from How to adjust Gmail for a smaller screen - TechRepublic
java - Instance Variable in JUnit - Stack Overflow
The reason for the list
not being updated the second time is because of the behavior of Junit
. Junit
creates an instance of the test class for each test. So, a new object is created for each test case and the list
is reinitialized every time.
Read full article from java - Instance Variable in JUnit - Stack Overflow
protocol buffers - Where is the (meta) .proto file which describes .desc files? - Stack Overflow
The format is FileDescriptorSet
as defined in descriptor.proto
:
https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.proto
descriptor.proto
is typically installed to /usr/include/descriptor.proto
or /usr/local/include/descriptor.proto
on Unix systems. descriptor.pb.h
is installed with the protobuf headers and descriptor.pb.cc
is compiled into the protobuf library, so you don't have to generate them yourself if you are using C++. Similarly, in Java, the com.google.protobuf.DescriptorProtos
class is compiled into the base library.
Read full article from protocol buffers - Where is the (meta) .proto file which describes .desc files? - Stack Overflow
Generic Parsing of PB in java - CTO=开发管理+架构+技术专栏 - CSDN博客
Is it possible to parse PB in a generic fashion in java ? I looked into GeneratedMessage and could not find a way to parse any PB byte buffer into a GeneratedMessage. Essentially, i am trying to parse a PB byte buffer into GeneratedMessage and then i would use reflection to detect fields inside it.Thanks in advance
Read full article from Generic Parsing of PB in java - CTO=开发管理+架构+技术专栏 - CSDN博客
这实际上是一个技术问题,涉及到iOS与安卓两个操作系统的设计原理。
首先,安卓机上大内存,这是个中国特色,也就是说只有中国国内销售的安卓机才会上这么大的内存,海外版的安卓机主流内存基本和苹果差不了太多。图我就不贴了,大家可以自己去查一下,华为的P30,海外版的128G硬盘的型号只配4G或6G内存,而中国版的P30,64G硬盘的型号却配上了8G内存;海外版的安卓机,128G硬盘配4G内存比比皆是,简直不要太多,但在国内,你几乎找不到一款128G硬盘配4G内存的安卓机。这样乍一看好像我们得了便宜,可其实,这是国产安卓生态的无奈之举。
先说国内安卓机为什么上大内存吧。举一个例子,比如我们常用的微信这个APP,首先你打开微信登录账号后,你手机上的微信APP就会和腾讯的服务器保持一个长久的连接,你发一条消息给你朋友,这条消息不是直接从你的手机上发到他的手机上的,而是你的手机将消息发给了腾讯的服务器,然后腾讯的服务器再发给你朋友。这个时候就有一个问题,如果你朋友手机上的微信APP处在关闭状态下,那么即使腾讯服务器把消息发过去了,他也收不到,因为他的手机上微信APP已经完全关闭了,已经和腾讯服务器断开连接了,只有当他再次打开微信的时候,连接恢复,他才能收到那条信息。也就是说,想要及时收到消息,那么微信这个APP就不能完全关闭,需要留下一些线程在后台一直保持运行,一直和腾讯的服务器保持接连,这样一旦收到消息,系统才能及时启动消息机制提醒你。
Read full article from iPhone 为什么不加大内存? - 知乎
本文起源于我在 Twitter 上发布的关于 Python 经历的一系列话题。
出于某些原因,想记录一下我过去数年使用 Python 的经验和一些感悟。 毕竟算是一门把我带入互联网行业的语言,而我近期已经几乎不再写 Py 代码, 做一个记录,也许会对他人起到些微的帮助,也算是纪念与感恩了。
推文地址:https://twitter.com/ppcelery/status/1159620182089728000
最早接触 py 是 2010 年左右,那之前主要是使用 c、fortran 和 matlab 做数值运算。当时在做一些文件文本处理时觉得很麻烦,后来看到 NASA 说要用 py 取代 matlab,就去接触了 py。
python 那极为简洁与优美的语法给了当时的我极大的震撼,时至今日,写 py 代码对我而言依然是一种带有艺术意味的享受。
首先开宗明义的说一句:python 并不慢,至少不够慢。拿一个 web 后端来说,一台垃圾 4 核虚机,跑 4 个同步阻塞的 django,假设 django 上合理利用线程分担了阻塞操作,假设每节点每秒可以处理 50 个请求(超低估),在白天的 10 小时内就可以处理 720 万请求。而这种机器跑一天仅需要 20 块钱。
Read full article from laisky-blog: Python 之路
目前Go语言主要活跃在区块链、云计算、命令行工具和后端服务等领域。这些领域基本上和GUI关系不大。近来出现了很多跨平台的Go GUI项目。虽说用井喷之势形容有些过了,但是的确有加速的迹象。难道Go语言将要开辟出另一大块疆土?
忙中偷闲,整理了一份目前GUI/图形/图像相关的Go项目列表。见下。欢迎补充。
(因为微信公众号文章不允许外链,所以对此文章的Go库感兴趣的同志可以直接访问 https://github.com/go-graphics/go-gui-projects 来查看这些库,)
原生GUI绑定
dlgs (https://github.com/gen2brain/dlgs) 是一个跨平台的显示对话框和输入框的Go代码库。
glfw (https://github.com/go-gl/glfw) 是一个GLFW3绑定库。
go-mobile (https://github.com/golang/mobile) 支持移动平台应用开发(Android和iOS)。(其中包含OpenGL ES 2.0和ES 3.0绑定库 (https://godoc.org/golang.org/x/mobile/gl) 。)
go-sdl2 (https://github.com/veandco/go-sdl2) 是一个SDL2绑定库。
go-gtk (https://github.com/mattn/go-gtk) 是一个GTK2绑定库。
gotk3 (https://github.com/gotk3/gotk3) 是一个GTK+3绑定库。
GXUI (https://github.com/google/gxui) ,Google员工出品,但已经停止维护很久。
qt (https://github.com/therecipe/qt) 是一个qt绑定库。
shiny (https://github.com/golang/exp/tree/master/shiny) 是一个跨平台的UI库。貌似荒废了。
Read full article from 2019,Go GUI项目爆发的一年?
如果你没有生活在上个世纪,并且是云计算或相关领域的一名搬砖者,那你应该听说最近 CentOS 8 官方正式版已经发布了,CentOS
完全遵守 Red Hat
的再发行政策,并且致力与上游产品在功能上完全兼容。CentOS 8 主要改动和 RedHat Enterprise Linux 8 是一致的,基于 Fedora 28 和内核版本 4.18
,其中网络方面的主要改动是用 nftables
框架替代 iptables
框架作为默认的网络包过滤工具。如果你还没有听说过 nftables,现在是时候学习一下了。
nftables 是一个 netfilter
项目,旨在替换现有的 {ip,ip6,arp,eb}tables 框架,为 {ip,ip6}tables 提供一个新的包过滤框架、一个新的用户空间实用程序(nft)和一个兼容层。它使用现有的钩子、链接跟踪系统、用户空间排队组件和 netfilter
日志子系统。
nftables 主要由三个组件组成:内核实现、libnl netlink 通信和 nftables 用户空间。 其中内核提供了一个 netlink
配置接口以及运行时规则集评估,libnl
包含了与内核通信的基本函数,用户空间可以通过 nft
和用户进行交互。
本文主要介绍用户空间命令行工具 nft
的用法。
1.
nftables VS iptables
nftables 和 iptables 一样,由表(table)、链(chain)和规则(rule)组成,其中表包含链,链包含规则,规则是真正的 action。与 iptables 相比,nftables 主要有以下几个变化:
iptables
规则的布局是基于连续的大块内存的,即数组式布局;而 nftables
的规则采用链式布局。其实就是数组和链表的区别,好像 Kubernetes 用户对此应该很兴奋?
iptables
大部分工作在内核态完成,如果要添加新功能,只能重新编译内核;而 nftables
的大部分工作是在用户态完成的,添加新功能很 easy,不需要改内核。
iptables
有内置的链,即使你只需要一条链,其他的链也会跟着注册;而 nftables
不存在内置的链,你可以按需注册。由于 iptables
内置了一个数据包计数器,所以即使这些内置的链是空的,也会带来性能损耗。
简化了 IPv4/IPv6
双栈管理
Read full article from CentOS 8 都发布了,你还不会用 nftables?
Chrome仍然是目前最好的浏览器,每天用Chrome 必然少不了使用扩展来增强浏览器的功能,这里整理下我常用的Chrome 扩展。
Read full article from 那些我常用的 Chrome 扩展
Read full article from 如何避免新代码变包袱?阿里通用方法来了!
generics - in Java syntax, Class - Stack Overflow
You're correct.
In Java generics, the ?
operator means "any class". The extends
keyword may be used to qualify that to "any class which extends/implements Something
(or is Something
).
Thus you have "the Class
of some class, but that class must be or extend/implement Something
".
Read full article from generics - in Java syntax, Class - Stack Overflow
serialization - Different deserialization behavior between Java 8 and Java 11 - Stack Overflow
As mentioned in the comments and encouraged by the asker, here are the parts of the code that changed between version 8 and version 11 that I assume to be the reason for the different behavior (based on reading and debugging).
The difference is in the ObjectInputStream
class, in one of its core methods. This is the relevant part of the implementation in Java 8:
Read full article from serialization - Different deserialization behavior between Java 8 and Java 11 - Stack Overflow
Oracle plans to dump risky Java serialization | InfoWorld
Oracle plans to drop from Java its serialization feature that has been a thorn in the side when it comes to security. Also known as Java object serialization, the feature is used for encoding objects into streams of bytes. Used for lightweight persistence and communication via sockets or Java RMI, serialization also supports the reconstruction of an object graph from a stream.
Removing serialization is a long-term goal and is part of Project Amber, which is focused on productivity-oriented Java language features, says Mark Reinhold, chief architect of the Java platform group at Oracle.
Read full article from Oracle plans to dump risky Java serialization | InfoWorld
Serialization of an Object of a class on 2 different JVMs in java - Stack Overflow
if you have serialVersionUID in your class, serialize/deserialize will not be a problem, but if serialVersionUID is missing in your code, as you are compiling class with both JVM(I understand, .class file has same content but compiled with different JVMs) in that case, serialVersionUID is assigned by java, which won't be same, hence serialize/deserialize will not work. So, add
private static final long serialVersionUID = -6903933977591709194L;
in case you haven't added, with any value, and compile as many times, rest assured, serialize/deserialize will work. :)
Read full article from Serialization of an Object of a class on 2 different JVMs in java - Stack Overflow
Serialization and De-Serialization in Java - DZone Java
We will get a RuntimeException
saying: Exception in thread "main" java.io.NotSerializableException: java.io.ObjectOutputStream.
SerialVersionUID
is an ID, which is stamped on an object when it gets serialized usually with the hashcode of the object. We can find serialVersionUID for the object by the serialver
tool in Java.
Syntax: serialver classname
SerialVersionUID
is used for version control of an object. The consequence of not specifying serialVersionUID
is that when you add or modify any field in the class, then the already-serialized class will not be able to recover because the serialVersionUID
was generated for the new class and the old serialized object will be different. The Java serialization process relies on correct serialVersionUID
for recovering the state of the serialized object and throws java.io.InvalidClassException in case of serialVersionUID
mismatch.
Read full article from Serialization and De-Serialization in Java - DZone Java
Serialization is mostly used in two areas:
prototyping of persistence
pretty much every object graph can quickly be made serializable, for quick proof-of-concepts or quick-and-dirty applications this might be faster than setting up a real ORM layer or other persistence system
short term storage of almost-arbitrary objects:
Applications servers, for example, have a tendency to persist session information using serialization. This has the advantage that the values in the session can be almost any type (as long as its serializable).
For almost all other uses, the drawbacks you (and the article) mentions are too big: the exact format is hard to keep stable, class changes can easily make your serialized data unreadable, reading/writing the data in non-Java code is almost impossible (or at least a lot harder than necessary).
Read full article from Java serialization - advantages and disadvantages, use or avoid? - Software Engineering Stack Exchange
This notion of Single Entry, Single Exit (SESE) comes from languages with explicit resource management, like C and assembly. In C, code like this will leak resources:
void f() { resource res = acquire_resource(); // think malloc() if( f1(res) ) return; // leaks res f2(res); release_resource(res); // think free() }
In such languages, you basically have three options:
Replicate the cleanup code.
Ugh. Redundancy is always bad.
Use a goto
to jump to the cleanup code.
This requires the cleanup code to be the last thing in the function. (And this is why some argue that goto
has its place. And it has indeed – in C.)
Introduce a local variable and manipulate control flow through that.
The disadvantage is that control flow manipulated through syntax (think break
, return
, if
, while
) is much easier to follow than control flow manipulated through the state of variables (because those variables have no state when you look at the algorithm).
In assembly it's even weirder, because you can jump to any address in a function when you call that function, which effectively means you have an almost unlimited number of entry points to any function. (Sometimes this is helpful. Such thunks are a common technique for compilers to implement the this
pointer adjustment necessary for calling virtual
functions in multiple-inheritance scenarios in C++.)
When you have to manage resources manually, exploiting the options of entering or exiting a function anywhere leads to more complex code, and thus to bugs. Therefore, a
Read full article from coding style - Where did the notion of "one return only" come from? - Software Engineering Stack Exchange
"Single Entry, Single Exit" was written when most programming was done in assembly language, FORTRAN, or COBOL. It has been widely misinterpreted, because modern languages do not support the practices Dijkstra was warning against.
"Single Entry" meant "do not create alternate entry points for functions". In assembly language, of course, it is possible to enter a function at any instruction. FORTRAN supported multiple entries to functions with the ENTRY
statement:
Read full article from coding style - Where did the notion of "one return only" come from? - Software Engineering Stack Exchange