我需要用 Java 组织我的垃圾收集逻辑。互联网上有关于如何编写自己的GC
视频甚至视频的文章。但在所有示例中,人们只是去С++
代码并开始展示示例。我不清楚如何将库与现有库连接GC
,已经存在哪些方法以及如何在启动时将自己的库连接GC
到我的进程。Java
faoxis's questions
有这个类:
@Data
@Accessors(chain = true)
@NoArgsConstructor
@Entity
class MyEntity {
@JsonProperty(access = JsonProperty.Access.READ_WRITE)
@Id
private String id;
private String birthPlace;
@UpdateTimestamp
private LocalDateTime updatedAt;
@CreatedDate
private LocalDateTime createdAt;
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
updatedAt = LocalDateTime.now();
}
@PreUpdate
protected void onUpdate() {
updatedAt = LocalDateTime.now();
}
}
我这样写测试:
String id = UUID.randomUUID().toString();
repository.save(new MyEntity().setId(id));
MyEntity savedEntity = repository.getOne(id);
assertNotNull(savedEntity.getCreatedAt());
assertNotNull(savedEntity.getUpdatedAt());
assertEquals(savedEntity.getCreatedAt(), savedEntity.getUpdatedAt());
Thread.sleep(100);
savedEntity = repository.save(repository.getOne(id).setBirthPlace("Moscow"));
assertNotNull(savedEntity.getCreatedAt());
assertNotNull(savedEntity.getUpdatedAt());
assertNotEquals(savedEntity.getCreatedAt(), savedEntity.getUpdatedAt());
在上面的测试repository
中,是这样的JpaRepository
。问题是钩子不起作用PrePersist
,但PreUpdate
它不起作用。不明白为什么。
该类的源代码SoftReference
有这个字段:
/**
* Timestamp updated by each invocation of the get method. The VM may use
* this field when selecting soft references to be cleared, but it is not
* required to do so.
*/
private long timestamp;
根据该方法的文档,每次调用都get
必须更新timestamp
. 但它没有,我不知道为什么。作为一个实验,我写了以下类:
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
public class SoftReferenceTest {
public static void main(String[] args) throws Exception {
SoftReference<StringBuilder> softReference = new SoftReference<>(new StringBuilder());
long timestamp = getTimestamp(softReference);
for (int i = 0; i < 10; i++) {
checkTimestampChange(softReference, timestamp);
}
}
private static void checkTimestampChange(SoftReference softReference, long timestampBefore) throws Exception {
softReference.get();
Thread.sleep(100);
assert timestampBefore == getTimestamp(softReference);
}
private static long getTimestamp(Object object) throws Exception {
Field timestampField = SoftReference.class.getDeclaredField("timestamp");
timestampField.setAccessible(true);
long timestamp = timestampField.getLong(object);
timestampField.setAccessible(false);
return timestamp;
}
}
代码运行成功,没有错误。我不明白为什么。
在我的实践中,在同一类中相同类型的字段的情况下,将 OOP 方法映射到关系数据库经常会出现问题。我无法理解如何以最有效的方式解决这样的问题。
更详细的例子:
我有一个Person
具有字段address
和workAddress
. 此外,两个子实体具有相同的字段集。
在代码中它看起来像这样(伪代码):
class Person
Address address
Address workAddress
如何使用编程语言来实现这一点很清楚。有一个问题是如何在数据库中制作它。例如,我可以这样做(伪sql
):
CREATE TABLE address (id SERIAL PRIMARY KEY);
CREATE TABLE PERSON (
id SERIAL PRIMARY KEY,
address FOREIGN KEY (address.id),
workdAddress FOREIGN KEY (address.id)
);
这会起作用,但从数据库理论的角度来看,它并不完全正确。毕竟,我们将有一个一对多的地址人端。甚至两次。
你也可以这样:
CREATE TABLE PERSON (
id SERIAL PRIMARY KEY
);
CREATE TABLE address_type (
id SERIAL PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE address (
id SERIAL PRIMARY KEY,
person_id FORIGN KEY(person.id),
address_type FORIGN KEY (address_type.id)
);
在这里,我们从关系模型的角度得到了正确的解决方案,但对于 OOP 来说却是一个非常糟糕的解决方案。这里的缺点是:JOIN
带有类型的附加表,在代码中使用它很不方便(您需要遍历所有地址才能找到正确的地址或补充选择)。
我一直在寻找最流行的解决方案ORM
- Hibernate
. 我没有找到任何东西来解决这样的问题(也许我看起来很糟糕)。
是否有任何共同的做法、工具或机制来处理此类问题?
我有这样的课:
import play.api.libs.json.Json
case class EmailRequest (apiKey: String, username: String)
object EmailRequest {
implicit val emailRequestWrites = Json.writes[EmailRequest]
}
它很好地转换为 json。只有 apiKey 字段有问题。客户希望收到一个 api_key,而我有一个 apiKey。
我可以以某种方式使卫星对象仅更改一个字段的名称吗?
我有这些case
课程:
case class Role(name: String)
case class User(id: Int, firstName: String, lastName: String, role: Role)
像这样的控制器:
class MyController @Inject() (cc: ControllerComponents) extends AbstractController(cc) {
def user = Action {
val user = User(1, "Petr", "Petrov", Role("USER"))
val userJson = Json.toJson(user)
println(userJson)
Ok(userJson)
}
}
根据文档,如果 User 类没有嵌套,那么我可以这样做:
implicit val userWrites = Json.writes[User]
val userJson = Json.toJson(user)
Ok(userJson)
但是由于 我在对象role
中有对象user
,它不起作用。
如何正确处理嵌套对象?
我有这样的配置(例如):
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
@Autowired
private SomeInterceptor someInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(someInterceptor);
}
}
在这里,从类继承用于指定特定设置WebMvcConfigurerAdapter
。我在哪里可以找到其他类,我的应用程序可以从这些类中继承并针对每个特定情况进行定制?
我需要执行以下命令集ansible
:
apt-get update && apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
apt-get install -y kubelet kubeadm kubectl
问题从第二行开始。通过ansible我这样做:
- name: curl curl
command: sudo curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
作为回应,我收到一个错误:
[WARNING]: Consider using 'become', 'become_method', and 'become_user' rather
than running sudo
fatal: [default]: FAILED! => {"changed": true, "cmd": ["sudo", "curl", "-s", "https://packages.cloud.google.com/apt/doc/apt-key.gpg", "|", "sudo", "apt-key", "add", "-"], "delta": "0:00:00.037295", "end": "2018-02-14 07:25:50.272885", "failed": true, "msg": "non-zero return code", "rc": 2, "start": "2018-02-14 07:25:50.235590", "stderr": "curl: option -: is unknown\ncurl: try 'curl --help' or 'curl --manual' for more information", "stderr_lines": ["curl: option -: is unknown", "curl: try 'curl --help' or 'curl --manual' for more information"], "stdout": "", "stdout_lines": []}
如何正确执行这样的命令?我试图在命令中添加一行sudo: true
并将其删除sudo
。错误不会消失。
我的时间是这样的"2017-12-04T15:45:11.635Z"
:
要转换为,Date
我将以下注释放在相应的字段上:
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-ddTHH:mm:ssZ")
这就是我收到此错误的原因:
{
"timestamp": 1512388174163,
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.web.client.RestClientException",
"message": "Could not extract response: no suitable HttpMessageConverter found for response type [class ru.something.api.domain.AwesomeObject] and content type [application/json;charset=UTF-8]",
"path": "/consent/test"
}
应该如何为正确的时间反序列化指定格式?
无法显示所有早于某个日期的记录。该请求给出了一个错误:
ORA-01861: 文字与格式字符串不匹配
SELECT *
FROM application app
JOIN product_type pt ON pt.ID = app.product_type_id
WHERE DATE(created_time) > DATE('2017/11/13');
也许有一些简单的方法?该字段created_time
的类型为TIMESTAMP
。
如果在请求过程中出现问题,它将RestController
抛出json
如下内容:
{
"timestamp": 1510417124782,
"status": 500,
"error": "Internal Server Error",
"exception": "com.netflix.hystrix.exception.HystrixRuntimeException",
"message": "ApplicationRepository#save(Application) failed and no fallback available.",
"path": "/application"
}
为此序列化了哪个类对象?我能以某种方式影响这个对象并在运行时输入这个对象的状态和消息吗?
此代码不起作用:
public static <T> void doSomething(Class clazz) {
List<clazz> list = new ArrayList<>();
}
如何将generic
变量放入 -type 中?
Java 中的线程与操作系统中的线程有什么关系?例如,UNIX 系统有线程系统调用。创建新线程时是否调用它?
也许我用谷歌搜索得很糟糕,但我在互联网上没有找到任何东西。看到有关该主题的一些文章的链接会很酷。
我做了这个二进制堆实现:
public class BinaryHeap {
private int[] elements;
public BinaryHeap(int[] elements) {
this.elements = elements;
for (int i = elements.length / 2 - 1; i >= 0; --i) {
siftDown(i);
}
}
public void add(int element) {
int[] newElements = new int[elements.length + 1];
System.arraycopy(elements, 0, newElements, 0, elements.length);
newElements[newElements.length - 1] = element;
elements = newElements;
siftUp(elements.length - 1);
}
public int extractMax() {
assert !isEmpty();
int result = elements[0];
elements[0] = elements[elements.length - 1];
deleteLast();
if (!isEmpty()) {
siftDown(0);
}
return result;
}
public boolean isEmpty() {
return elements.length == 0;
}
private void deleteLast() {
if (elements.length > 1) {
int[] newElements = new int[elements.length - 1];
System.arraycopy(elements, 0, newElements, 0, elements.length - 1);
elements = newElements;
} else {
elements = new int[0];
}
}
private void siftDown(int i) {
int left = 2 * i + 1;
int right = 2 * i + 2;
int largest = i;
if (left < elements.length && elements[left] > elements[i]) {
largest = left;
}
if (right < elements.length && elements[right] > elements[i]) {
largest = right;
}
if (largest != i) {
swap(i, largest);
siftDown(largest);
}
}
/**
* Проталкивание элемента наверх
* @param i - индес массива
*/
private void siftUp(int i) {
while (i > 0) {
int parent = (i - 1) / 2;
if (elements[i] < elements[parent])
return;
swap(i, parent);
i = parent;
}
}
private void swap(int index1, int index2) {
int temp = elements[index1];
elements[index1] = elements[index2];
elements[index2] = temp;
}
public int[] getElements() {
int[] elementsCopy = new int[elements.length];
System.arraycopy(elements, 0, elementsCopy, 0, elements.length);
return elementsCopy;
}
}
我写了这个小测试来测试它:
@Test
public void all() throws Exception {
BinaryHeap heap = new BinaryHeap(new int[] {});
heap = new BinaryHeap(new int[]{2, 42, 525, 35, 63, 81});
for (int i : heap.getElements()) {
System.out.print(i + " ");
}
System.out.println();
heap.getElements()[0] = 1241251;
assertEquals(heap.getElements()[0], 525);
heap.add(2425);
heap.add(1);
List<Integer> numbers = new ArrayList<>();
while (!heap.isEmpty()) {
numbers.add(heap.extractMax());
}
// numbers.forEach(e -> System.out.print(e + " "));
assertEquals((int) numbers.get(0), 2425);
assertEquals((int) numbers.get(1), 525);
assertEquals((int) numbers.get(2), 81);
assertEquals((int) numbers.get(3), 63);
assertEquals((int) numbers.get(4), 42);
assertEquals((int) numbers.get(5), 35);
assertEquals((int) numbers.get(6), 2);
assertEquals((int) numbers.get(7), 1);
}
问题出在方法extractMax
上。并不总是采用最大数量。怎么做才对?
我有一个这样的领域:
@ManyToOne
@JoinColumn(name = "organization_id")
@JsonIgnore
private Organization organization;
通常我不希望它出现在json
我通过@RestController
spring
'a. 但在某些情况下,我希望这个字段仍然显示。可能吗?
我想提出这样的请求:
SELECT count(*) FROM loan WHERE country = 'lv' AND created_at > current_timestamp - second(1)
如何用second(1)
有效的表达式替换它,以便它在h2
and中工作postgres
?
所有java
对象都可以包含mutable
和immutable
。很明显,例如,字符串是immutable
. 但是如果我想创建自己的immutable
类型,那么它必须满足什么要求呢?
我有一个这样的例子:
public class ImmutableObject {
private final String string;
private final Date date;
public ImmutableObject(String string, Date date) {
this.string = string;
this.date = date;
}
public Date getDate() {
return new Date(date.getTime());
}
public String getString() {
return string;
}
}
我可以认为它是不可变的吗?字段是必需的final
吗?如果其中一个字段,例如,一个字符串,不是final
,那么这个类的一个对象可以被认为是不可变的吗?这个类是否考虑到了多线程的所有缺陷?
事实上,这个问题是另一个问题的延续。
许多文章说,当您创建没有new
文字的字符串时,该字符串最终会出现在字符串池中。否则,需要一个方法intern
。那么如何解释下面的行为呢?
String s2 = "hello";
String s1 = "hello";
System.out.println(s1 == s2); // true
System.out.println("hel" + "lo" == "hello"); // true
s1 = "hello";
s2 = "hel";
String s3 = "lo";
System.out.println(s1 == s2 + s3); // false
System.out.println(s2 + s3 == "hel" + "lo"); //false
如果在后一种情况下它s2
指的是与文字“hel”相同的地方,并且具有s3
相同的故事,那么为什么"hel" + "lo"
它不等于(通过引用)s2 + s3
?
在许多有关java
(例如,“Java 哲学”)的书籍中,他们写道,在编写视图构造时,String s = "some string"
实际上会创建一个新对象String
,如下所示:String s = new String("some string")
.
那我为什么要这样做System.out.println(new String("a") == new String("a"))
并得到false
. 但万一System.out.println("a" == "a")
我收到true
.
为什么在第一种情况下jvm
创建了两个不同的对象,而在第二种情况下它指的是同一个对象?
在Shipilev 的演讲中,有一句话说在java
基类型中有 8 个类型原语和一个链接(8:30)。但是链接是包类之一java.lang.ref
,不是吗?如果,例如, WeekReference
是一个基本类型,那为什么Object
不是?